-
Notifications
You must be signed in to change notification settings - Fork 18
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
clients in other languages #11
Comments
Yeah, more language clients are on my radar, just haven't gotten to it yet (plus there's a lot of server stuff to do). I plan to do a Python and Java client next if someone else doesn't get to it first. Dart would be great too. Generating the gRPC code is actually very straightforward, I just need to get it properly documented. And like you said, there is pretty minimal code on top of what's provided by gRPC. |
Is there a nodejs client? |
Not at the moment, sorry. Generating the gRPC bindings give you a low-level client though. https://github.com/liftbridge-io/liftbridge-grpc I haven't had time to document this yet. |
Saw the python client and his notes about what extra code a client needs apart from grpc. https://github.com/dgzlopes/python-liftbridge#how-to-contribute |
@joeblew99 Agreed, I think it's to the point where we can document the steps for creating a client library. I'm planning to merge this this week which implements stream partitioning (and should be the last major API change before a stable release). Once this is merged I'll add some markdown detailing what's needed to implement a client. Maybe @dgzlopes can provide some input based on his work with the Python client. |
Wow exciting.
Looks like it might finally be ready for action.
I am planning to put a web gateway on top to make it easy to build
front-end.
https://github.com/dunglas/mercure
https://gitlab.com/wallforfry/dart_mercure
The way it works is to use SSE to push updates to front ends
Anyways just figured it is worth mentioning.
…On Wed, 28 Aug 2019, 17:28 Tyler Treat, ***@***.***> wrote:
@joeblew99 <https://github.com/joeblew99> Agreed, I think it's to the
point where we can document the steps for creating a client library. I'm
planning to merge this
<liftbridge-io/liftbridge#93> this week which
implements stream partitioning (and should be the last major API change
before a stable release). Once this is merged I'll add some markdown
detailing what's needed to implement a client. Maybe @dgzlopes
<https://github.com/dgzlopes> can provide some input based on his work
with the Python client.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#11?email_source=notifications&email_token=AC3RU45RDFHMBI2V6EOW3ULQG2KQJA5CNFSM4HNM7ONKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD5LQM6A#issuecomment-525796984>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AC3RU46YKB5CSFTKWW5DO7DQG2KQJANCNFSM4HNM7ONA>
.
|
@tylertreat I’d love to build a Node.js client! A quick note — it would be help if there were releases with changelogs so we could start tracking changes. |
Yeah, I plan to start doing releases now that there shouldn't be any more breaking changes to the API. Will definitely include changelogs. |
@tylertreat Sounds great! I've started work on the Node.js client ( EDIT I have a repro now —
The debug script attempts to create a new stream, then publish a few messages, then subscribes to the same stream (subject) and then publishes a few more messages. Expected output — Each published message should be printed to console (see relevant line). Actual output —
|
@paambaati It looks like it's failing on subscribe? I bet it's because Liftbridge first sends an empty message on the stream when a subscription is successfully created (or an error if not). Are you handling this case in the client? See the Go client for an example: Lines 591 to 593 in 6fbf530
|
I’m assuming that empty message conforms to the proto. @tylertreat My initial guess is the response couldn’t be parsed by gRPC, and hence the error code 13 (it is reserved only for serious errors). I’m gonna debug this externally with tools and see if I’m able to reproduce this. |
Yes, it is a normal proto message, so I'm not sure why you'd be hitting a parse error. I will see if I can spend some time looking at it today. |
@tylertreat After studying the Go client implementation more closely, I’ve also realized there’s a lot more I’ve yet to implement (for example, partitioners) and things I haven’t fully understood (like subjects and how they can have a Documentation about the key operations (publish, subscribe, fetch metadata, etc.) and how to implement clients would be super-helpful. If there’s a branch where they’re being worked on, I’ll be more than happy to contribute. I’m currently grokking more of the Go client codebase and plan to write down my version of a “How to write a Liftbridge client” too. |
Yep, I'm planning to write up a guide on implementing a client later this week. Partitioning was just merged. The client doesn't actually have to support it to start using Liftbridge since when you create a stream it consists of just a single partition by default, so publish and subscribe work as normal without a partitioner. |
A-ha! I didn’t know this. Would be great if the documentation also marked the fields as mandatory or optional. |
@paambaati I'm starting to sketch out a guide for implementing client libraries here. Still a work in progress... |
@tylertreat Looks great! Thanks for writing it. If I may, I have some feedback around it —
|
Love the shape the guide is taking! Also, one thing that I have on the Python client backlog is the usage of a connection pool. Actually, from the code docs:
Maybe a further explanation on the guide would be helpful. Also, now that docs are getting bigger and new libraries are being developed, migrating them to some central location using Mkdocs (or something similar) and CD/CI would be great. It would make the Liftbridge readme smaller too! On the other hand, having a release system would be really helpful for automatically building docker images [0] [0] https://github.com/dgzlopes/liftbridge-docker |
Also, I think defining a standard way to consume the bindings might be useful. Actually, go client uses the liftbridge-grpc [0] ones, the python/node clients builds them on fixed commit basis [1][2] and other clients even have the protos inside the repo [3]. One solution might be to use git submodules or to ship the bindings as a different package on each language, but I think this topic needs further discussion. From researching other projects using gRPC, seems like they are all doing it differently... So I think we should pick the approach that works the best for Liftbridge. [0] https://github.com/liftbridge-io/liftbridge-grpc |
@tylertreat @dgzlopes I'm still struggling with getting The debug script (shared earlier in #11 (comment)) publishes messages, but the responses always have an empty ack, and subscribe always returns a For example, here's a Message I'm publishing —
and here's the ack I get every time —
I'm fairly certain I'm doing something wrong in writing the payload or the subscribe semantics (because the code that the Go client handles on subscribe is |
@dgzlopes About the gRPC bindings, I use a method very similar to yours — see https://github.com/paambaati/node-liftbridge/blob/master/scripts/generate_grpc_code.sh |
Oops! My bad @paambaati, I will edit my latest comment. I saw the proto file being tracked and I though It was hardcoded on the repo. Also, I'm actually diving on your issue. Even if my skills on ts are really low right now I will try to identify anything gRPC/Liftbridge related that seems strange. |
@dgzlopes Thanks a lot! In the meanwhile, I ran a detailed trace, and here's what I get - https://gist.github.com/paambaati/7884b119eee47fafa436f74db8b59edc I'm grasping at straws here but I'm hoping this trace gives us some clue. I've padded the debug script's output with a lot of new lines so it is a little easier to read. |
@tylertreat @dgzlopes More debugging information! I tried running my debug script to publish some data and then subscribing to the same stream/subject using the example Go client, and turns out, it works (🥳) and I can see my data on the Go side. |
Sorry, I've been out of the office. Lots of threads of discussion here. :) Thanks for the feedback on the client implementation guide. I will make sure to include it!
@dgzlopes Totally agree. I'd like to set up a nicer docs solution.
Yep, open to discussion on that. I've been generating code in the liftbridge-grpc repo for use in libraries (just Go and Python right now), but not sure if that's the best approach or not. @paambaati I will try to take a look at your issue this week. Based on your most recent message, it sounds like publish might be working at least? Or is there still an issue with the ack? |
@tylertreat The ack is still undefined, sadly. But the subscribe via your Go client can read the messages published by my Node.js client. And about the client implementation guide, here’s what would be nice to have too —
These can probably be separated into a separate section that talks about higher-level utility functions while the rest can be called the low-level wire protocol or the basic communication APIs. |
And for the documentation, I’d suggest evaluating Docusaurus too. It is developed by Facebook and used by a lot of projects, and IMHO, looks really nice. I can also help with proof-reading the documentation and creating custom stylesheets for the docs to fit the Liftbridge theme. |
@tylertreat @dgzlopes I was finally able to narrow it down to the root cause! You can follow the full issue here. tl;dr The server responds to
Note the @tylertreat Is the |
@paambaati Yes, Also, I've started looking into the ack issue with publishes. I've been trying to wrap my head around the Typescript gRPC API, but I'm thinking the ack is |
@tylertreat @dgzlopes FWIW, I've narrowed the issue much further down to protocolbuffers/protobuf-javascript#43 While I can monkey-patch the fix, I'd rather not and I'm hoping we come up with a fix soon over at the In the meantime, I've finished implementing most of the methods (connection pooling and unit tests are left) and also have documentation up and running — https://paambaati.github.io/node-liftbridge/globals.html 🎉 |
@tylertreat I'm starting work on the connection pool and resubscribe logic, and I'm trying to understand your implementation. I have some questions if you don't mind answering them.
|
Interesting, I would expect gRPC clients to behave the same in terms of error codes. Not sure if that is unique to the Node implementation. My testing approach for the Go client was to simply kill and restart the server as you indicated. Perhaps it's appropriate for clients to handle this error case as well? At any rate, the resubscribe logic is purely best-effort resiliency. At the moment, it's on clients to track their position in the log if needed. Next up after I finish the client guide documentation work I will be implementing "consumer groups" which will have capabilities for automatically tracking log position similar to Kafka.
If there are items specific to the Node client, it might be easier to track discussion in a separate issue? Perhaps we can use this thread for discussing the in-progress client guide documentation (which I'm planning to return to later this week). |
Closing this issue with the introduction of client implementation docs. I've also created a separate issue for migrating docs to a proper documentation system. |
From the looks of things most of the code is GRPC code generated.
Would be cool to setup a docker to make the code for java, nodejs, Dart, etc.
Then i am guessing some people that use that language can write the extra code needed by looking at how simple it is in the golang code.
I think the Dart one would be pretty easy as i have done some GRPC with Dart. That would make Liftbridge work with Flutter.
Just noticed a ruby one:https://github.com/andyl/liftbridge_ruby
is there an Awesome Liftbridge list anywhere?
The text was updated successfully, but these errors were encountered: