Open hktechn0 opened 3 years ago
Thanks for pointing out.
Yeah, that's the heritage from when Decaton didn't support consuming arbitrary task format. (Initially, Decaton only supported DecatonTaskRequest
protobuf format)
When we introduced TaskExtractor
for supporting arbitrary message format, there was a discussion about how to support retry-feature.
serializedTask
as-is, and produce it to retry-topicserializedTask
differently depending on messages are DecatonTaskRequest
-format or in arbitrary format.DecatonTaskRequest
, serialziedTask
is a serialized_task
field in protobufserializedTask
has to be raw entire message bytes.DecatonTaskRequest
and arbitrary format in unified exactly same way, we have to migrate retried-task's messages to store entire message bytes in its serialized task field
DefaultTaskExtractor
(i.e. ProcessorsBuilder#consuming(String, Deserializer)
overload)~In short, you have to use DefaultTaskExtractor
only when you consume DecatonTaskRequest
format.~
In short, you have to use ProcessorsBuilder#consuming(String, Deserializer)
to consume DecatonTaskRequest
format.
I guess we can solve this problem fundamentally in this attempt (https://github.com/line/decaton/pull/80), but unfortunately it's now stuck due to our lack of resource.
In short, you have to use DefaultTaskExtractor only when you consume DecatonTaskRequest format.
We are using DecatonTaskRequest
format task with DefaultTaskExtractor
(with wrapped task extractor) and retrying.
I think the problem of the code is here https://github.com/line/decaton/blob/v3.0.2/processor/src/main/java/com/linecorp/decaton/processor/runtime/ProcessorsBuilder.java#L76
If we specify Deserializer
for .consuming()
, new DefaultTaskExtractor<>(deserializer)
for both taskExtractor
and retryTaskExtractor
.
https://github.com/line/decaton/blob/v3.0.2/processor/src/main/java/com/linecorp/decaton/processor/runtime/ProcessorsBuilder.java#L63
But if we specify TaskExtractor
for .consuming()
, retryTaskExtractor
will be wrapped with DefaultTaskExtractor
for consuming non DecatonTaskRequest
format topics even if taskExtractor
is DefaultTaskExtractor
.
https://github.com/line/decaton/blob/v3.0.2/processor/src/main/java/com/linecorp/decaton/processor/runtime/ProcessorsBuilder.java#L76
If we call .consuming()
with DefaultTaskExtractor
, deserialize DecatonTaskRequest
2 times and it failed.
I know TaskExtractor
is especially for non DecatonTaskRequest
, but it will cause a bug.
If it doesn't support DefaultTaskExtractor
, I think it should be thrown error or put logging on .cosuming()
.
In short, you have to use DefaultTaskExtractor only when you consume DecatonTaskRequest format
This my comment was bit wrong. Precisely, you have to use ProcessorsBuilder#consuming(String, Deserializer) to consume DecatonTaskRequest format.
If we call .consuming() with DefaultTaskExtractor, deserialize DecatonTaskRequest 2 times and it failed.
Yeah, right.
I understand that this behavior could cause a bug, but since DefaultTaskExtractor
is located in internal
package, we don't expect it to be used by users.
Though throwing an exception or logging is an option, if users "wrap" DefaultTaskExtractor (like you did) in outer extractor, it may not work.
I think adding some DefaultTaskExtractor
's javadoc about the caution for the usage is sufficient for now.
We are consuming Kafka topic using Decaton processor with retrying.
However,
ProcessorsBuilder.consuming(String topic, TaskExtractor<T> taskExtractor)
is not working correctly withDefaultTaskExtractor
.retryTaskExtractor
will unwrapDecatonTaskRequest
usingDefaultTaskExtractor
, thentaskExtractor.extract()
here. https://github.com/line/decaton/blob/v3.0.2/processor/src/main/java/com/linecorp/decaton/processor/runtime/ProcessorsBuilder.java#L76 But iftaskExtractor
isDefaultTaskExtractor
or aTaskExctractor
which is delegating deserialization toDefaultTaskExtractor
, deserialization will be failed onretryTaskExtractor
and the retrying task will be discarded.Stacktrace:
We passed original
com.linecorp.bot.commons.decaton.processor.TimedTaskExtractor
totaskExtractor
which is like following (written in Kotlin). ThisTimedTaskExtractor
is for observing consuming delay. The issue will cause with delegate =DefaultTaskExtractor
.