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

feat!: add and implement IReceiver #1219

Merged
merged 21 commits into from
Mar 31, 2023
Merged

feat!: add and implement IReceiver #1219

merged 21 commits into from
Mar 31, 2023

Conversation

weboko
Copy link
Collaborator

@weboko weboko commented Mar 6, 2023

Problem

We have Relay and Filter that have the same behaviour but do not share common interface. It makes harder to make interchangeable usage of these objects.

Solution

Create and implement IReceiver

Notes

@weboko
Copy link
Collaborator Author

weboko commented Mar 7, 2023

Currently this PR is for just showing possible approach.

In general I think since we are using observable term in the code, relying on subscription based way for retrieving data and using it-all or other utils for async operations we should reconsider our approach to work with data streams.

There are different things we can choose or continue using (callbacks, Promises, events etc).

I would like to highlight this - RxJS.
This is just an idea, we can chose something else. Main point is to unify similar operations we have.
My proposition is to use Observable.subscribe and Observer.next for public API.

Usage of the lib on that level will help us:

  • we would be able to use RxJS internally in our objects to run async operations;
  • unlock in using different utils from the lib;
  • consumers will be able to use RxJS with our objects;
  • and it does not enforce usage of the lib on the consumers;

If our common opinion would be to continue current approach it definitely makes sense to make interfaces are compatible (this work waku-org/js-noise#14) and try to come up with common approach for events that are owned by us (similarly to it #1213).

cc: @fryorcraken @danisharora099

@fryorcraken
Copy link
Collaborator

I think using RxJS for the receiver interface is fair and should hopefully help with js-noise and other consumers.

@weboko weboko marked this pull request as ready for review March 17, 2023 21:01
@weboko
Copy link
Collaborator Author

weboko commented Mar 17, 2023

I've been playing with idea of RxJS interfaces applied for receiver but has reached a conclusion it is an overkill.

In short - their usage will provide some extra features to consumers such as error handling but it is not clear if it will be used by anyone.

The other problem it will introduce a dependency and given that our bundle is quite big already it's better to add after this issue #579 is done.

I propose to refrain from using RxJS in this PR and research later and provide some PoC (will make an issue if we agree).

Do you even think it worth investigating, @fryorcraken?

@fryorcraken
Copy link
Collaborator

Do you even think it worth investigating, @fryorcraken?

We could have an issue in the icebox. As js-waku adoption grows, it may become a request from developers and in this case we could review.

addObserver<T extends IDecodedMessage>(
decoder: IDecoder<T>,
public subscribe<T extends IDecodedMessage>(
decoders: IDecoder<T>[],
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This change makes subscribe unified and accept decoders instead of one decoder.

@github-actions
Copy link

github-actions bot commented Mar 22, 2023

size-limit report 📦

Path Size Loading time (3g) Running time (snapdragon) Total time
Waku core 116.83 KB (+0.09% 🔺) 2.4 s (+0.09% 🔺) 2.4 s (-37.17% 🔽) 4.7 s
Waku default setup 387.93 KB (+0.1% 🔺) 7.8 s (+0.1% 🔺) 7.8 s (+23.19% 🔺) 15.5 s
ECIES encryption 27.99 KB (0%) 560 ms (0%) 1.9 s (-23.48% 🔽) 2.5 s
Symmetric encryption 27.99 KB (0%) 560 ms (0%) 1.9 s (-33.61% 🔽) 2.4 s
DNS discovery 108.07 KB (0%) 2.2 s (0%) 4.6 s (+53.35% 🔺) 6.7 s
Privacy preserving protocols 116.36 KB (+0.13% 🔺) 2.4 s (+0.13% 🔺) 3.7 s (-0.03% 🔽) 6 s
Light protocols 118.17 KB (+0.16% 🔺) 2.4 s (+0.16% 🔺) 2.4 s (-16.78% 🔽) 4.8 s
History retrieval protocols 118.19 KB (+0.11% 🔺) 2.4 s (+0.11% 🔺) 2.8 s (-24.18% 🔽) 5.1 s

decoders: IDecoder<T>[],
callback: Callback<T>,
opts?: ProtocolOptions
) => Unsubscribe<void> | Promise<Unsubscribe<Promise<void>>>;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is another thing I want to figure out - either make it sync or async for the interface.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Well, it is expected to have both:

  • Relay: all actions are local as the node relays all messages of the pubsub topic so listening (subscribe) or stopping to listen (unsubscribe) to given content topics are local actions hence it's sync
  • Filter: filtering of subscription is done by remote node, hence it's async

I don't see the dichotomy as an issue.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The problem here is that types are not reliable - we don't know if subscribe should be awaited or not, same goes for Unsubscribe.

packages/core/src/lib/relay/index.ts Outdated Show resolved Hide resolved
decoders: IDecoder<T>[],
callback: Callback<T>,
opts?: ProtocolOptions
) => Unsubscribe<void> | Promise<Unsubscribe<Promise<void>>>;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Well, it is expected to have both:

  • Relay: all actions are local as the node relays all messages of the pubsub topic so listening (subscribe) or stopping to listen (unsubscribe) to given content topics are local actions hence it's sync
  • Filter: filtering of subscription is done by remote node, hence it's async

I don't see the dichotomy as an issue.

packages/interfaces/src/receiver.ts Outdated Show resolved Hide resolved
packages/core/src/lib/relay/index.ts Outdated Show resolved Hide resolved
return new WakuNode(
options ?? {},
libp2p,
undefined,
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Idea for following improvement: make builders be props of protocolOptions object.

return (libp2p: Libp2p) => new Relay(libp2p, init);
}

export function wakuGossipSub(
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is a consequence of gossipSub being a property and not an extension of the Relay.
My opinion - it makes sense because Relay is our abstraction and GossipSub is a tool that we use to implement what we need.

cc: @fryorcraken

Copy link
Collaborator

Choose a reason for hiding this comment

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

I see how it is. I think it's fine for now. We can iterate on the API as we use it and get more feedback.

@weboko weboko requested a review from fryorcraken March 29, 2023 01:08
return (libp2p: Libp2p) => new Relay(libp2p, init);
}

export function wakuGossipSub(
Copy link
Collaborator

Choose a reason for hiding this comment

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

I see how it is. I think it's fine for now. We can iterate on the API as we use it and get more feedback.

@weboko weboko merged commit e11e5b4 into master Mar 31, 2023
@weboko weboko deleted the weboko/receiver branch March 31, 2023 01:17
@weboko weboko mentioned this pull request Apr 3, 2023
4 tasks
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.

2 participants