What is the difference between PubSub and Methods in Meteor?!
Can I put Methods in Server folder like Publishs?
To me seen like the same, but Methods is more reactive.
They are two different sides of the same coin. Here's a drawing of the data lifecycle in meteor:
Publish - Which data is sent from the server
Subscribe - Which data the client requests publications for
Methods - How to manipulate data from the client on the server
Note - this will typically be run on both on the client and the server. The client will make a prediction as to what the server will do so it can update right away. Then latency compensation will kick in when the method is run on the server and the canonical decision is made.
What is the difference between PubSub and Methods in Meteor?!
Publications are reactive and they provide a cursor. Subscription gets you the matching publication on clientside in a minimongo database. On the other hand, methods must be called instead of subscribed and they are mainly designed to execute server side tasks that you don't want to handle client side for many possible reasons.
More details here for publications: https://www.discovermeteor.com/blog/understanding-meteor-publications-and-subscriptions/
And here for methods:
http://meteortips.com/first-meteor-tutorial/methods/
Can I put Methods in Server folder like Publishs?
Yes you can and you should. For example, put them into server\methods
To me seen like the same, but Methods is more reactive.
This is the exact contrary. They are not the same, even if you can achieve similar results with both. Methods are by design not reactive, and pub/sub are.
Related
I would like to use the same service classes in both the publisher (which will be a REST API) and consumer. Since sending messages can be a part of these service classes, they have an instance of IBus injected into them so they can publish/send messages. This is fine on the REST API side, but the MassTransit documentation states the following:
Once you have consumers you will ALWAYS use ConsumeContext to interact with the bus, and never the IBus.
What's the reason behind this? Is it just performance related or does using IBus have any other consequences? And what are the alternatives to doing this? Would injecting IPublishEndpoint and ISendEndpointProvider be the accepted solution here, or does that not really change anything?
The reason why I want to do this is because some actions can be done either synchronously by using the API, or happen automatically in the background by using a message, and having to duplicate the business logic would be very inconvenient and hard to maintain.
Bonus question: The documentation states the same thing for TransactionalBus:
Never use the TransactionalBus or TransactionalEnlistmentBus when writing consumers. These tools are very specific and should be used only in the scenarios described.
However, if I want to support transactions in the above mentioned services, I will probably have to use TransactionalBus, but is it safe to do so in consumers? I do know about the in-memory outbox, but I have 2 problems with it:
It can only be used on the consumer side, so the publisher would not support transactions
It does not support "partial transactions" - the codebase that I'm working on has certain places where transactions don't wrap the entire API call, but rather only parts of it, so cases where some entities are successfully written to the database before the transaction is even started can happen, and in these cases the corresponding messages would need to be sent/published as well. This could easily be done by calling Release on the TransactionalBus at the right time, but couldn't be done when using the outbox since it's all or nothing (if an exception happens, nothing will be sent).
This bonus question isn't that important since I could probably work around it, but is still something I'm curious about, as it could be resolved by using TransactionalBus (if that won't cause any issues in consumers).
You should be using IPublishEndpoint or ISendEndpointProvider to publish or send messages from your components and/or services. There is almost never a reason to use IBus.
IPublishEndpoint and ISendEndpointProvider are registered a scoped, so a valid scope is required. In a service that normally doesn't have a scope, one can easily be created using provider.CreateScope(). Scopes should also be disposed of when they are no longer used.
Note that current versions should use provider.CreateAsyncScope() instead, and to make it easy just assign it using:
await using var scope = provider.CreateAsyncScope()
var publishEndpoint = scope.ServiceProvider.GetService<IPublishEndpoint>();
For any components, consumers, etc. simply use constructor injection for either of those two types, and they will resolve the proper services depending upon the context.
Also, don't use ITransactionBus. The new outbox is a better solution, as it's actually in the transaction. I will eventually remove ITransactionBus from MassTransit.
I'm a long-time Spring developer learning NestJS. The similarities are so striking, and I've loved how productive that's allowed me to be. Some documentation has me confused about one thing however.
I try to liken Nest "providers" to Spring beans with default scope. For example I create #Injectable service classes and think of them as analogous to Spring #Services. As such I've assumed these service classes needed to be thread safe - no state, etc. However, the Nest documentation here is a little ambiguous to me and kind of implies this might not be necessary (emphasis mine):
For people coming from different programming language backgrounds, it might be unexpected to learn that in Nest, almost everything is shared across incoming requests. We have a connection pool to the database, singleton services with global state, etc. Remember that Node.js doesn't follow the request/response Multi-Threaded Stateless Model in which every request is processed by a separate thread. Hence, using singleton instances is fully safe for our applications.
If individual requests aren't handled in their own threads, is it OK for Nest providers to contain mutable state? It would be up to the app to ensure each incoming request started with a "clean slate" - e.g. initializing that state with a NestInterceptor, for example. But to me, that doc reads that providers are created as singletons, and thus can be used as something akin to a wrapper container for data, like a ThreadLocal in Java.
Am I reading this wrong, or is this a difference in behavior between Nest and Spring?
You really should make request handling stateless.
I don't know anything about Spring, but in NestJS (and async javascript in general) it's single threaded, but doesn't block for I/O. That means the same thread of the same instance of a service can process multiple requests at once. It can only do one thing at a time, but it can start doing the next thing while the previous thing is waiting on a database query, or for the request to finish being transmitted, or for an external service to respond, or for the filesystem to deliver the contents of a file, etc.
So in one thread, with one instance of a service, this can happen:
Request A comes in.
Database query is dispatched for request A.
Request B comes in.
Database query is dispatched for request B.
Database query for request A returns, and the response is sent.
Database query for request B returns, and the response is sent.
What that means for state is that it will be shared between requests. If your service sets an instance property at one step of an async operation, then another async operation may start before the first was complete and set a new value for that instance property, which is probably not what you want.
I believe the "global state" the Nest docs mention is not per request, but general configuration state. Like the URL of an external service, or credentials to your database.
It's also worth mentioning that controllers receive a request object, which represents that specific request. It's common to add properties to that request object, like the current authenticated user for example. The request object can be passed around to give your controller and services context in a way that is friendly to this architecture.
I've been aware of event sourcing, CQRS, DDD and micro services for a little while and I'm now at that point where I want to try and start implementing stuff and giving something a go.
I've been looking into the technical side of CQRS and I understand the DDD concepts in there. How both the write side handles commands from the UI and publishes events from it, and how the read side handles events and creates projections on them.
The difficulty I'm having is the communication & a handling events from service-to-service (both from a write to read service and between micro services).
So I want to focus on eventstore (this one: https://eventstore.com/ to be less ambiguous). This is what I want to use as I understand it is a perfect for event sourcing and the simple nature of storing the events means I can use this for a message bus as well.
So my issue falls into two questions:
Between the write and the read, in order for the read side to receive/fetch the events created from the write side, am i right in thinking something like a catch up subscription can be used to subscribe to a stream to receive any events written to it or do i use something like polling to fetch events from a given point?
Between micro services, I am having an even harder time... So when looking at CQRS tutorials/talks etc... they always seem to talk with an example of an isolated service which receives commands from the UI/API. This is fine. I understand the write side will have an API attached to it so the user can interact with it to perform commands. E.g. create a customer. However... say if I have two micro services, e.g. a order micro service and an shipping micro service, how does the shipping micro service get the events published from the order micro service. Specifically, how does those customer events, translate to commands for the shipping service.
So let's take a simple example of: - Command created from the order's API to place an order. - A OrderPlacedEvent is published to the event store. How does the shipping service listen and react to this is it need to then DispatchOrder and create ain turn an OrderDispatchedEvent.
Does the write side of the shipping microservice then need to poll or also have a catch up subscription to the order stream? If so how does an event get translated to an command using DDD approach?
something like a catch up subscription can be used to subscribe to a stream to receive any events written to it
Yes, using catch-up subscriptions is the right way of doing it. You need to keep the stream position of your subscription persisted somewhere as well.
Here you can find some sample code that works. I am not posting the whole snippet since it is too long.
The projection service startup flow is:
Load the checkpoint (first time ever it would be the stream start)
Subscribe to the stream from that checkpoint
The runtime flow will then be:
The subscription will then call the function you provide when it receives an event. There's some plumbing there to do, like if you subscribe to $all, you need to filter out system events (it will be easier in the next version of Event Store)
Project the event
Store the new checkpoint
If you make your projections idempotent, you can store the checkpoint from time to time and save some IO.
how does the shipping micro service get the events published from the order micro service
When you build a brand new system and you have a small team working on all the components, you can make a shortcut and subscribe to domain events from another service, as you'd do with projections. Within the integration context (between the boxes), ordering should not be important so you can use persistent subscriptions so you won't need to think about checkpoints. Event Store will do it for you.
Be aware that it introduces tight coupling on the domain event schema of the originating service. Your contexts will have the Partnership relationship or the downstream service will be a Conformist.
When you move forward with your system, you might decide to decouple those contexts properly. So, you introduce a stable event API for the service that publishes events for others to consume. The same subscription that you used for integration can now instead take care of translating domain (internal) events to integration (external) events. The consuming context would then use the stable API and the domain model of the upstream service will be free in iterating on their domain model, as soon as they keep the conversion up-to-date.
It won't be necessary to use Event Store for the downstream context, they could just as well use a message broker. Integration events usually don't need to be persisted due to their transient nature.
We are running a webinar series about Event Sourcing at Event Store, check our web site to get on-demand access to previous webinars and you might find interesting to join future ones.
The difficulty I'm having is the communication & a handling events from service-to-service (both from a write to read service and between micro services).
The difficulty is not your fault - the DDD literature is really weak when it comes to discussing the plumbing.
Greg Young discusses some of the issues of subscription in the latter part of his Polygot Data talk.
Eventide Project has documentation that does a decent job of explaining the principles behind how the plumbing fits things together.
Between micro services, I am having an even harder time...
The basic idea: your message store is fundamentally a database; when the host of your microservice wakes up, it queries the message store for messages after some checkpoint, and then feeds them to your domain logic (updating its own local copy of the checkpoint as needed).
So the host pulls a document with events in it from the store, and transforms that document into a stream of handle(Event) commands that ultimately get passed to your domain component.
Put another way, you build a host that polls the database for information, parses the response, and then passes the parsed data to the domain model, and writes its own checkpoints.
I have a an application from which I need to send live updates to web clients.
I'm currently happily using websockets for that, via the WAMP protocol, as it provides both publish-subscribe and RPC methods.
Now, I find that in lots of situations, when a user starts the application or a view, I need to send an initial state to the client, and then keep sending updates. I do the first with an RPC call, and the latter via publish-subscribe.
Now, this forces me to write server-side and client-side code for both of the methods, even while I'm basically conveying the same information in both cases.
On server side, I'm moving appropriate code to a common method, but I still need to take care of both sending the event and provide an entry point for the RPC call:
# RPC endpoint for getting mission info
def get_mission_info(self):
return self.get_mission_info()
# Scheduled or manually called method to send mission info to all users
def publish_mission_info(self):
self.wamp.publish("UPDATE_INFO", [self.get_mission_info()])
def get_mission_info(self):
# Here we generate a JSON serializable dict with the info
return info
And you canimagine, client side (JS or Python) shows a similar duplicity (two handler methods).
Question is: is there a more clever way of handling this, and avoiding that boilerplate code? Some approach I could follow, perhaps automatically sending last event of each type just to clients that ask for it, or that just subscribed? Perhaps something at crossbar level?
In general terms, I feel I could be doing a better state synchronization strategy leveraging these two channels (pub-sub and RPC). How does people do it?
My WAMP server is Crossbar, and my client library is autobahn.js in Python and JS.
Who should be responsible for handling domain events? Application services, domain services or entities itself?
Let's use simple example for this question.
Let's say we work on shop application, and we have an application service dedicated to order operations. In this application Order is an aggregate root and following rules, we can work only with one aggregate within single transaction. After Order is placed, it is persisted in a database. But there is more to be done. First of all, we need to change number of items available in the inventory and secondly notify some other part of a system (probably another bounded context) that shipping procedure for that particular order should be started. Because, as already stated, we can modify only one aggregate within transaction, I think about publishing OrderPlacedEvent that will be handled by some components in the separate transactions.
Question arise: which components should handle this type of event?
I'd like to:
1) Application layer if the event triggers modification of another Aggregate in the same bounded context.
2) Application layer if the event trigger some infrastructure service.
e.g. An email is sent to the customer. So an application service is needed to load order for mail content and mail to and then invoke infrastructure service to send the mail.
3) I prefer a Domain Service personally if the event triggers some operations in another bounded context.
e.g. Shipping or Billing, an infrastructure implementation of the Domain Service is responsible to integrate other bounded context.
4) Infrastructure layer if the event need to be split to multiple consumers. The consumer goes to 1),2) or 3).
For me, the conclusion is Application layer if the event leads to an seperate acceptance test for your bounded context.
By the way, what's your infrastructure to ensure durability of your event? Do you include the event publishing in the transaction?
These kind of handlers belong to application layer. You should probably create a supporting application service's method too. This way you can start separate transaction.
I think the most common and usual place to put the EventHandlers is in the application layer. Doing the analogy with CQRS, EventHandlers are very similar to CommandHandlers and I usually put them both close to each other (in the application layer).
This article from Microsoft also gives some examples putting handlers there. Look a the image bellow, taken from the related article: