Skip to content

Fix: GroupUpdated send jobs could not be read back after a restart - #2211

Draft
mpretty-cyro wants to merge 1 commit into
devfrom
fix/group-updated-job-serialization
Draft

Fix: GroupUpdated send jobs could not be read back after a restart#2211
mpretty-cyro wants to merge 1 commit into
devfrom
fix/group-updated-job-serialization

Conversation

@mpretty-cyro

Copy link
Copy Markdown
Collaborator

MessageSendJob persisted its message with a bare Kryo. Kryo builds objects field by field, and parts of a protobuf message's object graph have no constructor it can call — so it writes one happily and then throws on the way back in:

KryoException: Class cannot be created (missing no-arg constructor): com.google.protobuf.UnknownFieldSet
Serialization trace:
  inner (org.session.libsession.messaging.messages.control.GroupUpdated)

Factory.create catches that, returns null, and JobQueue.resumePendingJobs deletes the row. Nothing leaks and nothing is reported — but no GroupUpdated queued for send survives an app restart: member-left, promote, info-change, member-change and invite-response are all silently dropped. One reported log carried 552 of these.

Changes

  • New JobKryo.kt: jobKryo() registers a Serializer<MessageLite> that round-trips protobuf through toByteArray()/parseFrom(), which is the only representation protobuf guarantees it can rebuild.
  • MessageSendJob and AttachmentUploadJob both use it, in both directions, so the write and read sides cannot drift apart.

No compatibility concern: a row containing a non-null protobuf field could not be read before this change either, so there is nothing already on disk that this stops being able to read.

Tests

JobKryoTest round-trips a GroupUpdated through the same Kryo the job uses. It fails without the serializer registration (with the exception above) and passes with it. Full suite green: 299/299.

Notes for review

The leave-retry-loop fix (separate PR) touches a different region of MessageSendJob; the two branches merge cleanly and can land in either order. Without this one, a leave interrupted by a restart silently does nothing.

MessageSendJob persisted its message with a bare Kryo, whose reflective field
serializer cannot construct a protobuf message on the way back in -- so every
queued GroupUpdated (member-left, promote, info-change, member-change,
invite-response) was written, failed to deserialize on the next launch, and had
its row deleted. Nothing leaked and nothing was reported: the message was simply
never sent. A leave interrupted by a restart therefore did nothing at all.

Protobuf fields now round-trip through their own wire format, and both message
jobs share one configured Kryo so the write and read directions cannot drift
apart again.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant