Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix channel's payload.data deserialization in RSocketMachine #277

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

palamccc
Copy link

Motivation:

In the current RSocketMachine._handleRequestChannel implementation, the payload is deserialized twice. So it leads to deserialization error when channels are used with serializers in RSocketServer.

This bug only affects 'channel' interaction model, not other interaction models.

Modifications:

The bug and the fix are explained in the code comments.
This PR only fixes the 0.x branch.

Result:

Added tests to test the deserialization and serialization path of the channel.
Fixes #217

@@ -784,13 +784,14 @@ class RSocketMachineImpl<D, M> implements RSocketMachine<D, M> {
}

_handleRequestChannel(streamId: number, frame: RequestChannelFrame): void {
const payload = this._deserializePayload(frame);
Copy link
Author

@palamccc palamccc Mar 31, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In all _handleXXXX methods, the frame is deserialized first. So in this method also, the payload should be deserialized first, before using it.

const existingSubscription = this._subscriptions.get(streamId);
if (existingSubscription) {
//Likely a duplicate REQUEST_CHANNEL frame, ignore per spec
return;
}

const payloads = new Flowable(subscriber => {
const payloads = new Flowable<Payload<D, M>>(subscriber => {
Copy link
Author

@palamccc palamccc Mar 31, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this bug (bug is explained in another code comment) was introduced mainly due to the missing type of this Flowable. so I added the type now.

const framesToPayloads = new FlowableProcessor(payloads, frame =>
this._deserializePayload(frame),
);
const framesToPayloads = new FlowableProcessor(payloads);
this._receivers.set(streamId, framesToPayloads);
Copy link
Author

@palamccc palamccc Mar 31, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug:
this._receivers is of type Map<number, ISubject<Payload<D, M>>>.
The subject is of type Payload<D, M>. i.e. deserialized payload. The subscribers of this subject can use the payload directly, its already deserliazed. The bug is, in the subscriber the payload is deserialized again and it's causing deserialization errors.

}
const data = this._serializers.data.serialize(payload.data);
const metadata = this._serializers.metadata.serialize(payload.metadata);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A minor bug fix: don't try to serialize metadata when metadata is not there. serialize it only when it exists.

Signed-off-by: Palani C <palani@canva.com>
@viglucci viglucci added needs triage Issue/PR needs triage by a project maintainer 0.x Issues relating to 0.x version(s) labels Jun 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
0.x Issues relating to 0.x version(s) needs triage Issue/PR needs triage by a project maintainer
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants