-
Notifications
You must be signed in to change notification settings - Fork 65
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(api): add support for websockets #48
Comments
@rixcian Hey, just wanted to say thanks for this well written ticket! The team is in general agreement that there's a need for something like this, and the details seem reasonable at least as a starting point. We have a lot of other work in flight as a team and probably can't take this on ourselves at the moment, but could provide support if you're interested. Is this something you have capacity to work on yourself? If so, we can spend more time reviewing the details. |
@djwhitt Hey, thanks for the kind words! Yeah, if you're okay with the specs, I'm ready to start working on this right away. |
@rixcian Great! We'll spend a bit more time digging in and get back to you with some design questions. |
Alright, first off, minor quibble. 😆
You do know that the indexed data is queryable using GraphQL, right? 🙂 |
Can expand a bit on why this format in particular was chosen. It seems like having a |
For single node, in memory data structures would be fine (I don't think Dragonfly DB is needed). Redis sounds good for a multi-node setup. Code should be written to an interface that can be implemented on both. It would also be very helpful to get a diagram of how you envision subscription state and message streams being managed in a multi-node setup. |
I'm also curious if you've considered the pros and cons of implementing our own websocket protocol vs using something like GraphQL subscriptions. |
Hey @rixcian! Thanks for issue, was about to create basically same issue myself. Writing special protocol for subscriptions would make it more performant, but would also require much more hours to do. @djwhitt LMK if you want PR with implementation of this functionality. |
// Our possible usecase, not important for overall discussion, but might explain why it's good idea. Good usecase for this would be some sort of system with a lot of updates not linked to each other (i.e a lot of SmartWeave contracts). In RareWeave, we have a lot of NFT contracts (hundreds), and we need to check for interactions for each of them. Currently it's done by chunking it to multiple queries, each responsible for specified range of contracts. Then rinse and repeat, syncing new interactions over time. |
Definitely important to hear uses cases!
I don't think we're quite ready for a PR on this, but if you wanted to take a stab at an architecture diagram for a multi-node setup as well, that could be helpful. |
@djwhitt Multi-node as in multiple ar.io nodes? Or something else? |
@angrymouse Yes. Assume that we have N ar.io nodes and the actual websocket can be connected to any of them. What's the architecture for streaming updates and maintaining subscription state. (note: there are probably some standard ways to do this with Apollo, but I haven't investigated them yet) |
Supportive of this. Would serve several use cases we'd be interested in pursuing with ArConnect. |
@t8, I'm interested in hearing more details about your use cases if you can share. |
@djwhitt I think there shouldn't be some kind of special protocol for keeping socket updated. Each node just streams its data once it received it (I.e loaded bundle or block) |
@angrymouse Do you mean unbundling, tx processing, etc. would only be streamed to the clients connected to the writer in a multi-node setup? |
To add a bit more context - the multi-node scenario we need to support initially is 1 DB writer with multiple readers, but in the future we may have more complex topologies with unbundling handled by different nodes than L1 TX indexing (that's how arweave.net works today). We don't have to have all that sorted out initially, but we do need to have a design that accommodates growth in that direction. |
@djwhitt If I understood correctly, we still can just do 1 writer>readers. Just that readers can be subscribed to multiple writers in case some of them doesn't process needed chunk of data. |
@angrymouse I think we might be talking about different kinds of readers and writers. The scenario I'm thinking about is when you have 2 ar.io gateway services running. One of them reads and writes to a DB. The other one only reads. Both accept connections from users. We need a way for the users connected to the reader to receive the same messages as the users connected to the writer. |
Summary
Create a WebSocket server for
ar.io
gateways to enable users/developers to subscribe to events on Arweave.Motivation
There's no service that would enable event subscription in the Arweave ecosystem via
websockets
.Use cases for devs
Other motivations
ws
in the space right now, so it would be a good selling point forar.io
WS_ENABLED
variable in.env
Specification
Because WebSockets doesn't follow any strict rules/protocols there's a need to create its own communication protocol.
This is a type specification of each message in this new protocol:
Example of communication
It works by subscribing to particular events. The gateway will return a subscription ID. For each event that matches the subscription, a notification with relevant data is sent together with the subscription ID.
subscribe to all new txs
):ar.io
gateway (returns a subscription id -uuid v4
):Event methods
ar_subscribe
ar_subscribe_accepted
ar_subscribe_denied
ar_subscribe_msg
ar_unsubscribe
Event types
new_tx
owner
: stringtarget
: stringtags
: { name: string, value: string }[]Transaction[]
new_block
Block
Rate-limiting
ws
server by:This would probably need some discussion if it's needed or not.
ENVs
WS_ENABLED
| type:boolean
| default:false
| desc:Start the WebSocket server
WS_PORT
| type:number
| default:3333
| desc:Port of the WebSocket server
WS_CORS
| type:string
| default:*
| desc:Allow access from specific origin
Implementation details
ws
module inNode.js
should be sufficientredis
(or dragonflydb) in-memory db for storing subscription IDs and params or use just own implementation of some structure?Considerations
It's the first blueprint, so there will likely be some blind spots that I've missed. Feedback is highly appreciated. :)
The text was updated successfully, but these errors were encountered: