Comments (38)
@akramtexas I can only agree! ^^
from cloudstate.
This travis build https://travis-ci.com/marcellanz/cloudstate/jobs/232175160
captures my efforts of the weekend to get a 100% pass on the TCK and build integration into the existing travis CI build job.
My goal for the next week is now to have a proposal for the Go Client API by somewhere the end of the week based on this implementation. I also plan to write some documentation similar to existing or planned API documentation of the other language implementations.
I'm looking forward to discussions and future work to get a full implementation of the Go Client API.
(first CloudState TCK 100% pass on travis-ci.org)from cloudstate.
@marcellanz In broad strokes—yes. The user's code interfaces with the proxy via the CloudState gRPC protocol, so for every language "implementation" a gRPC server will be running in that process, the proxy will connect to it via the CloudState protocol, and the only interactions via the proxy and the user code's process will be over gRPC. This means that any programming language which can have a gRPC server is a possible candidate to use CloudState.
the java-support and the node-support libraries exist to remove the need for every user to implement the CloudState protocol themselves, and to provide a language-appropriate end-user API for the users to write their stateful entities in. This also means that there can be any number of end-user APIs for every language, it just happens that me and James are more fluent in Akka to base the java-support implementation on that.
There are so many benefits to this approach—since the proxy does all the data access, we can keep track of DB-metrics completely isolated from user code metrics (think latencies and such).
Since the proxy is given the gRPC protocol for the user's service, it can seamlessly proxy it, and not only that, we can generate HTTP+JSON endpoints for all those gRPC endpoints. The proxy also exposes the users gRPC protocol via gRPC Server Reflection, so all tooling which understands that can use it (think ServerReflection2OpenAPI, or grpc_cli).
from cloudstate.
This evening was pretty productive. After two longer code reading sessions with the implementation of EventSourcedImpl
I got into how things have to work I think and then after having GetCart
implemented for the first time and running with the TCK, most of the rest of the shopping cart example went quicker and I had some fun.
Accordingly to the TCK, the implemetation lacks proper handling of events through EventSourcedReply
and I don't yet support snaphots.
The implementation for now is completely in PoC quality and I have to find out how the API might look like from a "API client" user perspective. Then having proper build integration into the project and some documentation will be next. And then the CRDT (new for me) and the function protocol., and I'm sure I missed some stuff.
( the flow of TCK."verify that items can be added to, and removed from, a shopping cart" )
from cloudstate.
from cloudstate.
Is there any work already done or stated to support Go? I think I can't spot any, even on other branches.
Does "Go Support" mean, having Go as a Client API?
from cloudstate.
Yes, a client API along the lines of the client APIs in JavaScript and Java (which is essentially a glorified gRPC client). Sorry for the really poor description on this issue.
from cloudstate.
from cloudstate.
Thanks for the pointer and offer to help. I like the motivation for the project and would love to see a Go Client – API for it. Let me get a grasp on it by reading the README and existing client API... if I can be helpful I'd be happy to do so.
from cloudstate.
Sounds great. Thank you.
from cloudstate.
So after reading the README, some parts a few times, as well as code, I come back to your offer to guidance. I bluntly and with my own words re-phrase what I have the impression of the implementation. Coming from JAVA/JVM/Go space mainly I confess not to understand too much about Scala code. So bear with me if I ask too stupid questions or assumptions of mine; I'm sure some are:
The IR (CIR) sems to be paramount to understand expected semantics of a "client". Cloudstate Procotol gRPC definitions together with IR semantics are the solely interface a foreign client API.
A client API implementation is like an SPI implementing gRPC services (technically). So here the API implementation enables entities to get called and treated by the IR semantics of being CRDTs, EventSourced or a Function(?). The Sidecar (in the reference implementation Akka based) beside the CloudState protocol does not know much about a client, gets opaque gRPC domain definitions through discovery and calls the clients "code".
Entity IDs, beside that the entity behaves according to the protocol, are the most concrete property the Akka Sidecar knows about them through its type.
Persistence is done by the Akka Sidecar and transparent for the client. At most the client has a small context it holds and persists domain objects, like to implement snapshots.
What happens on a "Client API" is completely separated from the Akka Sidecar, so if I see "akka imports" in CloudStateRunner.scala there are no shortcuts to any Akka "stuff" and it might be used for convenience (Having the JS API surely prooves that I think).
Am I off the rails or is that kind of accurate (I'm sure I miss a lot oft stuff) what the "API Client" can be characterised of or what it sees from its perspective?
from cloudstate.
Thank you.
from cloudstate.
Today I made some progress with a go-support API client with which I'm quite happy for a first stint and a few hours. Having one of the TCK tests green and the EntityDiscoveryManager happy with the EntitySpec it gets back from the go client with the shopping-chart example, including dependency protos.
Its raw and needs lot more work, but I closed some circles and I got into all things I did not knew before. Going forward, I think I'll make all the TCK tests happy and then refactor it into an idiomatic go library.
But for now, its good how it is and I like how things came together.
(CloudStateProxy is satisfied first time with what he gets from Discovery from the "other side")from cloudstate.
That's great news. Thanks for the update.
from cloudstate.
from cloudstate.
I have the second bullet green on the TCK but I'm pretty sure that the TCK is too kind with the current implementation as it is not complete for sure. I'm currently going down to implement the EventSourced service.
The points where I could get some help are regarding how to build the project (properly).
I honestly don't know how to build the project properly I think from a "sbt" point of view.
Either I did something wrong, but I:
- don't have a proxy/core/target/scala-2.12/akka-proxy.jar that is needed kind of by the TCK an there the cloudstate-tck.combinations proxy configuration in the application.conf. I currently start io.cloudstate.proxy.CloudStateProxyMain manually in IntelliJ and let the proxy by the TCK just not start.
- to get io.cloudstate.samples.shoppingcart.Main started from the project/module java-shopping-cart, I had to add for a) the tck and b) java-shopping-cart module to cloudstate-java-support as dependencies, otherwise without a) as an example EventSourcedImpl would not find anything by
import io.cloudstate.protocol
and without b) nothing byimport com.example.shoppingcart
.
I think I understand dependencies in general but with sbt I'm a bit lost :-D
I imported the project in IntelliJ like in the screenshot shown below. I build with IntelliJ and also tried on the CLI or with "sbt shell" by:
- sbt compile
- sbt package
from cloudstate.
from cloudstate.
sbt it:test
@viktorklang, that worked, thanks.
from cloudstate.
@marcellanz You're most welcome! I'll make sure that the documentation gets improved in that regard.
from cloudstate.
Cool—having support for Go would be awesome! Go Support means being able to implement CloudState entities in Go, in the same fashion as the JS support and Java support. You can wire the TCK to test against the reference implementation of the proxy. See the application.conf in the TCK for inspiration. We can help guiding you on how to hook things up. The best start is to look at either the JS and/or Java support.
…
-- Cheers, √
This is going to be so 🆒
from cloudstate.
Go has an opinionated behaviour when it comes to maps iteration order.
Since Go 1.0, iterating maps has an unpredictable and random order when it comes to iterating maps and, depending on the implementation of stuff, the following can happen
The TCK here expects the order of a shopping carts LineItems
to be predictable, which isn't for this implementation.
Go being opinionated in this brought some eyebrows up sometimes, even if defined in the Spec:
The iteration order over maps is not specified and is not guaranteed to be the same from one iteration to the next.
But I find it refreshing that it forces now the question if the TCK should respect that from an implementation @viktorklang
from cloudstate.
@marcellanz That's a great question! In this case, isn't it the iteration order of a sequence though?
from cloudstate.
Good morning Marcel
I was planning to start from scratch with this task a week ago, but I've seen that you've been advancing a lot of work. If you're happy with sharing with me your code I can have a look at it and start contributing there.
Regarding to your last input, I think it might be helpful to solve this problem if you used channels (https://tour.golang.org/concurrency/2) to guarantee the messaging order?
Kind Regards
Arturo
from cloudstate.
Good morning gentlemen 🌞: @marcellanz, @viktorklang, @ArturoTarinVillaescusa
@marcellanz - I like a lot two of your observations in particular, both spot on 🎯
- Go has an opinionated behavior when it comes to maps iteration order.
- But I find it refreshing that it forces now the question if the TCK should respect that from an implementation @viktorklang
- Oh yes, Go has raised some eyebrows for sure 😉
- Here's some thinking—followed by a snippet containing a workaround—which you may find helpful in solving the
ordering
(akasequencing
) problem at hand when working with Gomaps
:
The Go language designers noticed that people were relying on the fact that keys were normally stored in the order they were added in, so they randomized the order in which the keys are iterated over. Thus, if you want to output keys in the order they were added in, you need to keep track of which value is in which position in the order yourself like so:
import "sort"
var m map[int]string
var keys []int
for k := range m {
keys = append(keys, k)
}
sort.Ints(keys)
for _, k := range keys {
fmt.Println("Key:", k, "Value:", m[k])
}
- More details here at the following, excellent article, online: A Surprising Feature of Golang that Colored Me Impressed - I hope this helps...
- Good luck 🍀
from cloudstate.
Also please check out: go-maps-in-action 🗺
from cloudstate.
I was planning to start from scratch with this task a week ago, but I've seen that you've been advancing a lot of work. If you're happy with sharing with me your code I can have a look at it and start contributing there.
Hi @ArturoTarinVillaescusa. Sure, I'll be happy to share. I currently work to get the current TCK 100% passed and having a proposal for the client API. I'm not comfortable to share the state of code I have at the moment, but with the progress I made the last few days I'm pretty sure I can propose a first version of the go api client with which we can move on sometimes this week or the end of it.
There is plenty of stuff to do and I'm sure and looking forward to any contributions to it :-) Next steps will be CRDTs and the function protocol I think or anything the community is thinking of.
Regarding to your last input, I think it might be helpful to solve this problem if you used channels (https://tour.golang.org/concurrency/2) to guarantee the messaging order?
The order of the shopping cart items that get back by issuing the ShoppingCart#GetCart
command during development of the shopping cart example was backed by a map[string]LineItems
where the key of the map was the product_id. I then simply replied by ranging over the values of the map. This had the effect of getting random order of the line items which was affected by Go's random iteration order as I stated in my comment above. I changed that now to be in line with the TCKs expectations.
I'm not quite sure if I understand how channels would assure the order of the lines items added to the cart but I'm happy to discuss and hear what your idea was to do that.
from cloudstate.
Good morning gentlemen 🌞: @marcellanz, @viktorklang, @ArturoTarinVillaescusa
@marcellanz - I like a lot two of your observations in particular, both spot on 🎯
- Here's some thinking—followed by a snippet containing a workaround—which you may find helpful in solving the
ordering
(akasequencing
) problem at hand when working with Gomaps
:The Go language designers noticed that people were relying on the fact that keys were normally stored in the order they were added in, so they randomized the order in which the keys are iterated over. Thus, if you want to output keys in the order they were added in, you need to keep track of which value is in which position in the order yourself like so:
import "sort" var m map[int]string var keys []int for k := range m { keys = append(keys, k) } sort.Ints(keys) for _, k := range keys { fmt.Println("Key:", k, "Value:", m[k]) }
Good evening @akramtexas. Thanks for the pointers about maps in Go. I was fast implementing the cart using a map
and not something like java.util.LinkedHashMap
that is used by the java-shopping-cart
and then told by the TCK to be wrong. I think its valid to expect the order in the cart to be the same as the line items got into it. I fixed that and now the TCK is happy with that.
Regarding your proposed code, which I captured into a Go Playground snipped:
https://play.golang.org/p/PvD5hEsk3Vf
I think that snipped does not ensure the order properly. The keys get sorted, but that sorting clears , as an example, the order of something like 3,1,2,4 into 1,2,3,4. How was the snipped to retain the order? Looking forward to your ideas. Best Regards, Marcel
from cloudstate.
@marcellanz Wow! Congratulations—the feeling when the TCK passes is a great one, for sure! ^^
from cloudstate.
@viktorklang thanks, it felt great :-)
from cloudstate.
from cloudstate.
@viktorklang I will. Give me a bit more time to make it "right"…
from cloudstate.
@marcellanz Absolutely! :)
from cloudstate.
@viktorklang I think I will PR this today. I have some tasks left but documented them.
from cloudstate.
Very cool @marcellanz! Please add //TODO //FIXME on everything which you know that might represent edge-cases or otherwise, this makes it easier for others to spot things which may not be optimal yet.
Also, if you have time, it's really great to have a bit of rationale w.r.t. the end-user API, if there are any opportunities for improvements or otherwise. :)
Thanks for spending your time and efforts on this important feature!
from cloudstate.
Very cool @marcellanz! Please add //TODO //FIXME on everything which you know that might represent edge-cases or otherwise, this makes it easier for others to spot things which may not be optimal yet.
I will do and already had on a number of places. I'll go through it again and mark where appropriate.
Also, if you have time, it's really great to have a bit of rationale w.r.t. the end-user API, if there are any opportunities for improvements or otherwise. :)
I started the usual documents under cloudstate/docs/.../user/lang/go. I'll finish it and update the PR with an explaining gettingstarted.md and similar eventsourced.md as the Java one.
from cloudstate.
I will do and already had on a number of places. I'll go through it again and mark where appropriate.
Perfect, thank you!
I started the usual documents under cloudstate/docs/.../user/lang/go. I'll finish it and update the PR with an explaining gettingstarted.md and similar eventsourced.md as the Java one.
Nice!
from cloudstate.
@marcellanz ...
@viktorklang The PR branch has now documentation for go support.
from cloudstate.
Check here for future/current progress of Go Support in CloudState: https://github.com/cloudstateio/go-support
from cloudstate.
Related Issues (20)
- TCK: order of state action updates for addItem by the value entity ShoppingCart HOT 4
- Empty streamed responses are not actually connected HOT 2
- Dead letter logs on CRDT entity passivation HOT 1
- Failure: multiple grpc services in the same package HOT 1
- Projections for value entities
- HTTP API default mappings HOT 1
- Docker build error for Dockerfile.js-shopping-cart HOT 3
- Documentation on How to get started is not complete
- How / when are new versions of cloudstate-proxy-dev-mode published HOT 5
- Upgrade to akka-persistence-spanner 1.0.0-RC5 HOT 16
- Add local cache images layer for docker images on build HOT 5
- [proto] having gRPC service names PascalCase'd and others. HOT 1
- Usability issue with CRUD entity naming HOT 9
- Native-image Cassandra smoke test is flaky HOT 2
- nil pointer exception in spanner_store.go
- K8s Resource limits not applied to user functions HOT 2
- Additional conditions not managed properly when reconciling StatefulService
- NPM module postinstall fails on Windows
- A proposal to find and agree on a common protocol to discover services HOT 5
- The wrong site HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cloudstate.