Skip to content

Instantly share code, notes, and snippets.

@wplong11
wplong11 / TaskGroupExtensionTest.swift
Last active December 20, 2023 09:00
TaskGroup Syntax Sugar
import XCTest
final class TaskGroupExtensionTest: XCTestCase {
func testWhenAll() async throws {
// 모든 Task 가 완료될 때 까지 기다리고 인자 순서대에 맞춰서 결괏값 목록 반환
// Act
let results = await TaskGroup.whenAll(
{ await self.fetchTestDataAsync(numberOfInvocation: 0, delay: .microseconds(100)) },
{ await self.fetchTestDataAsync(numberOfInvocation: 1, delay: .microseconds(100)) },
{ await self.fetchTestDataAsync(numberOfInvocation: 2, delay: .microseconds(100)) },
@wplong11
wplong11 / RateLimiterTest.kt
Last active January 20, 2023 03:25
3가지 방식의 RateLimiter 로직 비교
package im.toss.home.batch
import io.github.resilience4j.kotlin.ratelimiter.executeSuspendFunction
import io.github.resilience4j.ratelimiter.RateLimiter
import io.github.resilience4j.ratelimiter.RateLimiterConfig
import io.github.resilience4j.ratelimiter.RateLimiterRegistry
import mu.KotlinLogging
import org.junit.jupiter.api.Test
import java.time.Duration
import java.time.LocalDateTime
import java.lang.Exception
fun main() {
runrunrun {
defer { println("HI") }
defer { println("HI") }
defer { println("HI") }
println("HELLO")
println("HELLO")
@wplong11
wplong11 / NativeMethodInvoker.ts
Created August 30, 2022 12:27
NativeMethodInvoker.ts
type NativeMethodRequest<TParams> = {
invocationId: string;
methodName: string;
params?: TParams;
};
type NativeMethodResponse = {
invocationId: string;
callbackType: 'resolve' | 'reject';
value?: any;
@wplong11
wplong11 / DispatchTimeIntervalExtension.swift
Created July 17, 2022 12:33
DispatchTimeIntervalExtension.swift
import Foundation
extension DispatchTimeInterval {
func asTimeInterval() -> TimeInterval {
switch self {
case let .nanoseconds(value): return Double(value) / 1_000_000_000
case let .microseconds(value): return Double(value) / 1_000_000
case let .milliseconds(value): return Double(value) / 1_000
case let .seconds(value): return Double(value)
case .never: return Double.infinity
@wplong11
wplong11 / QueryDSL.kt
Last active March 16, 2022 14:42
QueryDSL.kt
fun anyOf(
items: Collection<Predicate>,
): BooleanBuilder = BooleanBuilder().andAnyOf(*items.toTypedArray())
fun anyOf(
vararg args: Predicate?,
): BooleanBuilder = andAnyOf(args.filterNotNull())
fun allOf(
items: Collection<Predicate>,
@wplong11
wplong11 / JsonConverter.kt
Created January 14, 2022 10:32
Mapping string to complex object for @RequestParam
import com.fasterxml.jackson.databind.ObjectMapper
import org.springframework.core.convert.TypeDescriptor
import org.springframework.core.convert.converter.GenericConverter
import org.springframework.stereotype.Component
@Component
class JsonConverter(
private val objectMapper: ObjectMapper
) : GenericConverter {
override fun getConvertibleTypes() = mutableSetOf(
@wplong11
wplong11 / RemoteWebDriverPool.kt
Last active December 24, 2021 10:22
selenium 인스턴스 풀 관리
import kotlinx.coroutines.sync.Semaphore
import java.util.concurrent.ConcurrentLinkedQueue
open class ObjectPool<T : Any>(
capacity: Int,
private val instanceFactory: () -> T,
) {
private val semaphore = Semaphore(permits = capacity)
private val queue = ConcurrentLinkedQueue<T>()
@wplong11
wplong11 / AbstractSpliterator_Sequence.kt
Last active December 6, 2021 02:19
Java AbstractSpliterator vs Kotlin Sequence
class JsonObjectSpliterator<T>(
private val mapper: ObjectMapper,
private val inputStream: InputStream,
private val clazz: Class<T>
) : Spliterators.AbstractSpliterator<T>(Long.MAX_VALUE, NONNULL or IMMUTABLE) {
private val parser: JsonParser by lazy {
mapper.createParser(inputStream.reader(Charsets.UTF_8)).also {
check(it.nextToken() === JsonToken.START_ARRAY) { "Expected content to be an array" }
}
}
@wplong11
wplong11 / WebView+customization.kt
Last active November 22, 2021 01:54
Android 웹뷰 사용 경험 개선을 위한 확장 함수. 네이티브 앱을 쓰는 것 처럼 느껴지게 하는 함수들을 제공한다.
fun WebView.disableTouchCalloutAndUserSelect() {
this.evaluateJavascript("""
(function() {
const head = document.getElementsByTagName('head')[0];
const style = document.createRange().createContextualFragment(`
<style type="text/css">
*:not(input):not(textarea) {
-webkit-touch-callout: none;
-webkit-user-select: none;
}