Skip to content

Commit a506a8b

Browse files
committed
Add ChatClient.Build.fastEventParsing for enabling the new event parser.
1 parent 29ca2ca commit a506a8b

7 files changed

Lines changed: 87 additions & 12 deletions

File tree

stream-chat-android-client/api/stream-chat-android-client.api

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ public final class io/getstream/chat/android/client/ChatClient$Builder : io/gets
281281
public final fun debugRequests (Z)Lio/getstream/chat/android/client/ChatClient$Builder;
282282
public final fun disableDistinctApiCalls ()Lio/getstream/chat/android/client/ChatClient$Builder;
283283
public final fun disableWarmUp ()Lio/getstream/chat/android/client/ChatClient$Builder;
284+
public final fun fastEventParsing (Z)Lio/getstream/chat/android/client/ChatClient$Builder;
284285
public final fun fileTransformer (Lio/getstream/chat/android/client/uploader/FileTransformer;)Lio/getstream/chat/android/client/ChatClient$Builder;
285286
public final fun fileUploader (Lio/getstream/chat/android/client/uploader/FileUploader;)Lio/getstream/chat/android/client/ChatClient$Builder;
286287
public final fun forceInsecureConnection ()Lio/getstream/chat/android/client/ChatClient$Builder;
@@ -322,11 +323,13 @@ public final class io/getstream/chat/android/client/ClientExtensionsKt {
322323
public final class io/getstream/chat/android/client/api/ChatClientConfig {
323324
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLio/getstream/chat/android/client/logger/ChatLoggerConfig;ZLio/getstream/chat/android/client/notifications/handler/NotificationConfig;)V
324325
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLio/getstream/chat/android/client/logger/ChatLoggerConfig;ZZLio/getstream/chat/android/client/notifications/handler/NotificationConfig;)V
325-
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLio/getstream/chat/android/client/logger/ChatLoggerConfig;ZZLio/getstream/chat/android/client/notifications/handler/NotificationConfig;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
326+
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLio/getstream/chat/android/client/logger/ChatLoggerConfig;ZZLio/getstream/chat/android/client/notifications/handler/NotificationConfig;Z)V
327+
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLio/getstream/chat/android/client/logger/ChatLoggerConfig;ZZLio/getstream/chat/android/client/notifications/handler/NotificationConfig;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V
326328
public final fun getApiKey ()Ljava/lang/String;
327329
public final fun getCdnHttpUrl ()Ljava/lang/String;
328330
public final fun getDebugRequests ()Z
329331
public final fun getDistinctApiCalls ()Z
332+
public final fun getFastEventParsing ()Z
330333
public final fun getHttpUrl ()Ljava/lang/String;
331334
public final fun getLoggerConfig ()Lio/getstream/chat/android/client/logger/ChatLoggerConfig;
332335
public final fun getNotificationConfig ()Lio/getstream/chat/android/client/notifications/handler/NotificationConfig;

stream-chat-android-client/src/main/java/io/getstream/chat/android/client/ChatClient.kt

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4731,6 +4731,7 @@ internal constructor(
47314731
private var retryPolicy: RetryPolicy = NoRetryPolicy()
47324732
private var distinctApiCalls: Boolean = true
47334733
private var debugRequests: Boolean = false
4734+
private var fastEventParsing: Boolean = false
47344735
private var repositoryFactoryProvider: RepositoryFactory.Provider? = null
47354736
private var uploadAttachmentsNetworkType = UploadAttachmentsNetworkType.CONNECTED
47364737
private var fileTransformer: FileTransformer = NoOpFileTransformer
@@ -4997,6 +4998,22 @@ internal constructor(
49974998
this.debugRequests = shouldDebug
49984999
}
49995000

5001+
/**
5002+
* Enables the fast event-parsing path for incoming WebSocket events.
5003+
*
5004+
* When enabled, supported event types are parsed directly into domain models, bypassing
5005+
* the DTO intermediate layer. Unsupported event types fall back to the default DTO-based
5006+
* parser, so behavior is preserved for events the fast path does not yet handle.
5007+
*
5008+
* Currently supported event types:
5009+
* - `message.new`
5010+
*
5011+
* Disabled by default. The set of supported event types may grow over time.
5012+
*/
5013+
public fun fastEventParsing(enabled: Boolean): Builder = apply {
5014+
this.fastEventParsing = enabled
5015+
}
5016+
50005017
/**
50015018
* Sets a custom [RetryPolicy] used to determine whether a particular call should be retried.
50025019
* By default, no calls are retried.
@@ -5070,8 +5087,9 @@ internal constructor(
50705087
warmUp = warmUp,
50715088
loggerConfig = ChatLoggerConfigImpl(logLevel, loggerHandler),
50725089
distinctApiCalls = distinctApiCalls,
5073-
debugRequests,
5074-
notificationConfig,
5090+
debugRequests = debugRequests,
5091+
notificationConfig = notificationConfig,
5092+
fastEventParsing = fastEventParsing,
50755093
)
50765094
setupStreamLog()
50775095

stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api/ChatClientConfig.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ import io.getstream.chat.android.client.notifications.handler.NotificationConfig
3434
* @param distinctApiCalls Controls whether [DistinctChatApi] is enabled or not.
3535
* @param debugRequests Controls whether requests can be recorded or not.
3636
* @param notificationConfig A notification config to be used by the client.
37+
* @param fastEventParsing Enables the fast event-parsing path for incoming WebSocket events.
38+
* When `true`, supported event types are parsed directly into domain models, bypassing the DTO
39+
* intermediate layer; unsupported event types fall back to the default DTO-based parser.
40+
* Currently supported event types: `message.new`. Disabled by default.
3741
*/
3842
@Suppress("LongParameterList")
3943
public class ChatClientConfig @JvmOverloads constructor(
@@ -46,6 +50,7 @@ public class ChatClientConfig @JvmOverloads constructor(
4650
public var distinctApiCalls: Boolean = true,
4751
public val debugRequests: Boolean,
4852
public val notificationConfig: NotificationConfig,
53+
public val fastEventParsing: Boolean = false,
4954
) {
5055
public var isAnonymous: Boolean = false
5156
}

stream-chat-android-client/src/main/java/io/getstream/chat/android/client/di/ChatModule.kt

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -165,12 +165,16 @@ constructor(
165165
}
166166
private val eventMapping by lazy { EventMapping(domainMapping) }
167167

168-
private val directEventParser by lazy {
169-
DirectEventParser(
170-
currentUserIdProvider = currentUserIdProvider,
171-
messageTransformer = apiModelTransformers.incomingMessageTransformer,
172-
userTransformer = apiModelTransformers.incomingUserTransformer,
173-
)
168+
private val directEventParser: DirectEventParser? by lazy {
169+
if (config.fastEventParsing) {
170+
DirectEventParser(
171+
currentUserIdProvider = currentUserIdProvider,
172+
messageTransformer = apiModelTransformers.incomingMessageTransformer,
173+
userTransformer = apiModelTransformers.incomingUserTransformer,
174+
)
175+
} else {
176+
null
177+
}
174178
}
175179

176180
private val moshiParser: ChatParser by lazy {

stream-chat-android-client/src/main/java/io/getstream/chat/android/client/parser2/MoshiChatParser.kt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package io.getstream.chat.android.client.parser2
1818

19+
import android.util.Log
1920
import com.squareup.moshi.JsonAdapter
2021
import com.squareup.moshi.Moshi
2122
import io.getstream.chat.android.client.api2.FlagRequestAdapterFactory
@@ -59,9 +60,13 @@ import retrofit2.converter.moshi.MoshiConverterFactory
5960
internal class MoshiChatParser(
6061
private val eventMapping: EventMapping,
6162
private val dtoMapping: DtoMapping,
62-
private val directEventParser: DirectEventParser,
63+
private val directEventParser: DirectEventParser?,
6364
) : ChatParser {
6465

66+
init {
67+
Log.d("X_PETAR", "DEP: $directEventParser")
68+
}
69+
6570
private val moshi: Moshi by lazy {
6671
Moshi.Builder()
6772
.addAdapter(DateAdapter())
@@ -143,8 +148,9 @@ internal class MoshiChatParser(
143148
private val chatEventDtoAdapter = moshi.adapter(ChatEventDto::class.java)
144149

145150
private fun parseAndProcessEvent(raw: String): ChatEvent {
146-
val directEvent = directEventParser.parse(raw)
151+
val directEvent = directEventParser?.parse(raw)
147152
if (directEvent != null) {
153+
Log.d("X_PETAR", "Event from DEP: ${directEvent.type}")
148154
// Direct adapters handle enrichment inline — no enrichIfNeeded() needed.
149155
return directEvent
150156
}

stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/MoshiChatParserTest.kt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@
1717
package io.getstream.chat.android.client.parser2
1818

1919
import io.getstream.chat.android.client.events.ChatEvent
20+
import io.getstream.chat.android.client.events.NewMessageEvent
21+
import io.getstream.chat.android.client.parser2.testdata.NewMessageEventTestData
2022
import org.junit.jupiter.api.Assertions.assertEquals
23+
import org.junit.jupiter.api.Assertions.assertTrue
24+
import org.junit.jupiter.api.Nested
25+
import org.junit.jupiter.api.Test
2126
import org.junit.jupiter.params.ParameterizedTest
2227
import org.junit.jupiter.params.provider.MethodSource
2328

@@ -32,4 +37,37 @@ internal class MoshiChatParserTest {
3237
val parsedEvent = parser.fromJson(eventData, ChatEvent::class.java)
3338
assertEquals(expectedEvent, parsedEvent)
3439
}
40+
41+
@Nested
42+
inner class FastEventParsingToggle {
43+
44+
@Test
45+
fun `falls back to DTO path when fast event parsing is disabled`() {
46+
val parserWithoutFastPath = ParserFactory.createMoshiChatParser(fastEventParsing = false)
47+
48+
val event = parserWithoutFastPath.fromJson(
49+
NewMessageEventTestData.jsonAllFields,
50+
ChatEvent::class.java,
51+
)
52+
53+
assertTrue(event is NewMessageEvent)
54+
}
55+
56+
@Test
57+
fun `fast and DTO paths produce the same event for message_new`() {
58+
val parserWithFastPath = ParserFactory.createMoshiChatParser(fastEventParsing = true)
59+
val parserWithoutFastPath = ParserFactory.createMoshiChatParser(fastEventParsing = false)
60+
61+
val fastResult = parserWithFastPath.fromJson(
62+
NewMessageEventTestData.jsonAllFields,
63+
ChatEvent::class.java,
64+
)
65+
val dtoResult = parserWithoutFastPath.fromJson(
66+
NewMessageEventTestData.jsonAllFields,
67+
ChatEvent::class.java,
68+
)
69+
70+
assertEquals(dtoResult, fastResult)
71+
}
72+
}
3573
}

stream-chat-android-client/src/test/java/io/getstream/chat/android/client/parser2/ParserFactory.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ internal object ParserFactory {
2525
fun createMoshiChatParser(
2626
currentUserIdProvider: () -> String = { "" },
2727
apiModelTransformers: ApiModelTransformers = ApiModelTransformers(),
28+
fastEventParsing: Boolean = true,
2829
): MoshiChatParser = MoshiChatParser(
2930
eventMapping = EventMapping(
3031
DomainMapping(
@@ -42,6 +43,6 @@ internal object ParserFactory {
4243
currentUserIdProvider = currentUserIdProvider,
4344
messageTransformer = apiModelTransformers.incomingMessageTransformer,
4445
userTransformer = apiModelTransformers.incomingUserTransformer,
45-
),
46+
).takeIf { fastEventParsing },
4647
)
4748
}

0 commit comments

Comments
 (0)