Skip to content

Commit a03a1a0

Browse files
turnipdabeetsclaude
andcommitted
refactor(queue): generic PostHogQueue<Record> + EndpointSpec
Lift per-endpoint variations (codec, send, retry policy, runtime knobs) out of inlined branches in PostHogQueue and into a single EndpointSpec object. PostHogQueue becomes generic on Record so events, session replay, and future endpoints share one queue implementation, three instances. No behavior change for events or session replay. The recordUuid spec lambda preserves the existing event.uuid filename matching. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent cb2b4ed commit a03a1a0

18 files changed

Lines changed: 418 additions & 101 deletions

File tree

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
"posthog": patch
3+
"posthog-android": patch
4+
"posthog-server": patch
5+
---
6+
7+
Refactor `PostHogQueue` to be generic on `Record` and introduce `EndpointSpec`
8+
for per-endpoint codec, send, retry policy, and runtime knobs. No behavior
9+
change for events or session replay; sets up future log-record support without
10+
duplicating queue plumbing.

posthog-android/src/main/java/com/posthog/android/PostHogAndroidConfig.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.posthog.android
33
import com.posthog.PostHogConfig
44
import com.posthog.android.replay.PostHogReplayQueue
55
import com.posthog.android.replay.PostHogSessionReplayConfig
6+
import com.posthog.internal.EndpointSpec
67
import com.posthog.internal.PostHogApiEndpoint
78
import com.posthog.internal.PostHogQueue
89

@@ -26,7 +27,12 @@ public open class PostHogAndroidConfig
2627
apiKey = apiKey,
2728
host = host,
2829
queueProvider = { config, api, endpoint, storagePrefix, executor ->
29-
val defaultQueue = PostHogQueue(config, api, endpoint, storagePrefix, executor)
30+
val spec =
31+
when (endpoint) {
32+
PostHogApiEndpoint.BATCH -> EndpointSpec.batch(config, api, storagePrefix)
33+
PostHogApiEndpoint.SNAPSHOT -> EndpointSpec.snapshot(config, api, storagePrefix)
34+
}
35+
val defaultQueue = PostHogQueue(config, spec, executor)
3036
if (endpoint == PostHogApiEndpoint.SNAPSHOT) {
3137
val replayQueue = PostHogReplayQueue(config, defaultQueue, storagePrefix, executor)
3238
(config as? PostHogAndroidConfig)?.replayQueueHolder = replayQueue

posthog-android/src/main/java/com/posthog/android/replay/PostHogReplayBufferQueue.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ internal class PostHogReplayBufferQueue(
9090
*
9191
* Returns the number of events successfully migrated.
9292
*/
93-
fun migrateAllTo(targetQueue: PostHogQueueInterface): Int {
94-
if (targetQueue !is PostHogQueue) {
93+
fun migrateAllTo(targetQueue: PostHogQueueInterface<PostHogEvent>): Int {
94+
if (targetQueue !is PostHogQueue<*>) {
9595
config.logger.log("Replay buffer migration skipped: target queue is not PostHogQueue")
9696
return 0
9797
}

posthog-android/src/main/java/com/posthog/android/replay/PostHogReplayQueue.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ import java.util.concurrent.ExecutorService
1919
*/
2020
internal class PostHogReplayQueue internal constructor(
2121
private val config: PostHogConfig,
22-
private val innerQueue: PostHogQueueInterface,
22+
private val innerQueue: PostHogQueueInterface<PostHogEvent>,
2323
replayStoragePrefix: String?,
2424
private val executor: ExecutorService,
25-
) : PostHogQueueInterface {
25+
) : PostHogQueueInterface<PostHogEvent> {
2626
private val replayDir = replayStoragePrefix?.let { File(it, config.apiKey) }
2727

2828
private val bufferQueue: PostHogReplayBufferQueue =

posthog-android/src/test/java/com/posthog/android/replay/PostHogReplayBufferQueueTest.kt

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ package com.posthog.android.replay
33
import com.posthog.PostHogConfig
44
import com.posthog.PostHogEvent
55
import com.posthog.android.API_KEY
6+
import com.posthog.internal.EndpointSpec
67
import com.posthog.internal.PostHogApi
7-
import com.posthog.internal.PostHogApiEndpoint
88
import com.posthog.internal.PostHogQueue
99
import com.posthog.internal.PostHogQueueInterface
1010
import org.junit.Rule
@@ -33,7 +33,7 @@ internal class PostHogReplayBufferQueueTest {
3333

3434
private val executors = mutableListOf<ExecutorService>()
3535

36-
private class FakeQueue : PostHogQueueInterface {
36+
private class FakeQueue : PostHogQueueInterface<PostHogEvent> {
3737
val events = mutableListOf<PostHogEvent>()
3838

3939
override fun add(event: PostHogEvent) {
@@ -143,12 +143,10 @@ internal class PostHogReplayBufferQueueTest {
143143
config: PostHogConfig,
144144
storagePrefix: String,
145145
executor: ExecutorService = createExecutor(),
146-
): PostHogQueue {
146+
): PostHogQueue<PostHogEvent> {
147147
return PostHogQueue(
148148
config,
149-
PostHogApi(config),
150-
PostHogApiEndpoint.SNAPSHOT,
151-
storagePrefix,
149+
EndpointSpec.snapshot(config, PostHogApi(config), storagePrefix),
152150
executor,
153151
)
154152
}

posthog-android/src/test/java/com/posthog/android/replay/PostHogReplayIntegrationTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ internal class PostHogReplayIntegrationTest {
4444
private val context = mock<Context>()
4545
private val replayExecutors = mutableListOf<ExecutorService>()
4646

47-
private class FakeQueue : PostHogQueueInterface {
47+
private class FakeQueue : PostHogQueueInterface<PostHogEvent> {
4848
override fun add(event: PostHogEvent) {
4949
}
5050

posthog-android/src/test/java/com/posthog/android/replay/PostHogReplayQueueTest.kt

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ package com.posthog.android.replay
33
import com.posthog.PostHogConfig
44
import com.posthog.PostHogEvent
55
import com.posthog.android.API_KEY
6+
import com.posthog.internal.EndpointSpec
67
import com.posthog.internal.PostHogApi
7-
import com.posthog.internal.PostHogApiEndpoint
88
import com.posthog.internal.PostHogQueue
99
import com.posthog.internal.PostHogQueueInterface
1010
import org.junit.Rule
@@ -34,7 +34,7 @@ internal class PostHogReplayQueueTest {
3434
executors.clear()
3535
}
3636

37-
private class FakeQueue : PostHogQueueInterface {
37+
private class FakeQueue : PostHogQueueInterface<PostHogEvent> {
3838
val events = mutableListOf<PostHogEvent>()
3939
var flushCallCount = 0
4040
var startCallCount = 0
@@ -160,9 +160,7 @@ internal class PostHogReplayQueueTest {
160160
val innerQueue =
161161
PostHogQueue(
162162
config,
163-
PostHogApi(config),
164-
PostHogApiEndpoint.SNAPSHOT,
165-
storagePrefix,
163+
EndpointSpec.snapshot(config, PostHogApi(config), storagePrefix),
166164
executor,
167165
)
168166
val queue = PostHogReplayQueue(config, innerQueue, storagePrefix, executor)

posthog-server/src/main/java/com/posthog/server/internal/PostHogMemoryQueue.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ internal class PostHogMemoryQueue(
3131
private val executor: ExecutorService,
3232
private val retryDelaySeconds: Int = DEFAULT_RETRY_DELAY_SECONDS,
3333
private val maxRetryDelaySeconds: Int = DEFAULT_MAX_RETRY_DELAY_SECONDS,
34-
) : PostHogQueueInterface {
34+
) : PostHogQueueInterface<PostHogEvent> {
3535
private val events: ArrayDeque<PostHogEvent> = ArrayDeque()
3636
private val eventsLock = Any()
3737
private val timerLock = Any()

posthog/api/posthog.api

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,17 @@ public final class com/posthog/errortracking/PostHogErrorTrackingConfig {
488488
public final fun setAutoCapture (Z)V
489489
}
490490

491+
public final class com/posthog/internal/EndpointSpec {
492+
public static final field Companion Lcom/posthog/internal/EndpointSpec$Companion;
493+
public static final fun batch (Lcom/posthog/PostHogConfig;Lcom/posthog/internal/PostHogApi;Ljava/lang/String;)Lcom/posthog/internal/EndpointSpec;
494+
public static final fun snapshot (Lcom/posthog/PostHogConfig;Lcom/posthog/internal/PostHogApi;Ljava/lang/String;)Lcom/posthog/internal/EndpointSpec;
495+
}
496+
497+
public final class com/posthog/internal/EndpointSpec$Companion {
498+
public final fun batch (Lcom/posthog/PostHogConfig;Lcom/posthog/internal/PostHogApi;Ljava/lang/String;)Lcom/posthog/internal/EndpointSpec;
499+
public final fun snapshot (Lcom/posthog/PostHogConfig;Lcom/posthog/internal/PostHogApi;Ljava/lang/String;)Lcom/posthog/internal/EndpointSpec;
500+
}
501+
491502
public final class com/posthog/internal/EvaluationReason {
492503
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;)V
493504
public final fun component1 ()Ljava/lang/String;
@@ -832,8 +843,8 @@ public final class com/posthog/internal/PostHogPrintLogger : com/posthog/interna
832843
}
833844

834845
public final class com/posthog/internal/PostHogQueue : com/posthog/internal/PostHogQueueInterface {
835-
public fun <init> (Lcom/posthog/PostHogConfig;Lcom/posthog/internal/PostHogApi;Lcom/posthog/internal/PostHogApiEndpoint;Ljava/lang/String;Ljava/util/concurrent/ExecutorService;)V
836-
public fun add (Lcom/posthog/PostHogEvent;)V
846+
public fun <init> (Lcom/posthog/PostHogConfig;Lcom/posthog/internal/EndpointSpec;Ljava/util/concurrent/ExecutorService;)V
847+
public fun add (Ljava/lang/Object;)V
837848
public fun clear ()V
838849
public fun flush ()V
839850
public final fun getQueueDirectory ()Ljava/io/File;
@@ -843,7 +854,7 @@ public final class com/posthog/internal/PostHogQueue : com/posthog/internal/Post
843854
}
844855

845856
public abstract interface class com/posthog/internal/PostHogQueueInterface {
846-
public abstract fun add (Lcom/posthog/PostHogEvent;)V
857+
public abstract fun add (Ljava/lang/Object;)V
847858
public abstract fun clear ()V
848859
public abstract fun flush ()V
849860
public abstract fun start ()V

posthog/src/main/java/com/posthog/PostHog.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public class PostHog private constructor(
6262
private val featureFlagsCalledLock = Any()
6363
private val cachedPersonPropertiesLock = Any()
6464

65-
private var replayQueue: PostHogQueueInterface? = null
65+
private var replayQueue: PostHogQueueInterface<PostHogEvent>? = null
6666

6767
private val remoteConfig: PostHogRemoteConfig?
6868
get() = config?.remoteConfigHolder

0 commit comments

Comments
 (0)