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.
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.
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.
I am looking to implement an synchronous request-reply pattern using JMS inside a Java EE container. The sequence would be something like this
Browser makes a request to web application for data. This is a blocking request (say on thread T1).
The web app needs to connect to a remote web service to fulfill the above request. So it forms a request and places it on a queue (with a reply-to queue also declared).
The remote service processes the requests and places the response on to the reply-to queue declared in step 2
The response is read from the reply-to Q in the web app and made available to the blocking thread T1 of step 1.
I have followed the answer provided by T.Rob (How to match MQ Server reply messages to the correct request)
QueueReceiver queueReceiver =
session.createReceiver(destination, "JMSCorrelationID='customMessageId'");
TextMessage receivedMessage = (TextMessage)queueReceiver.receive( 15000 );
Is the above solution valid when running in a Java EE container (web module) where there could be multiple concurrent requests coming in?
This depends on the perception of "valid": It will probably compile and work. But from the design perspective, one could say that you can really improve it.
If your thread is blocking, any asynchronous communication won't add any value. Instead it will make it slow, it will consume resources, and it might even create trouble (see link below).
Whatever service is exposed by the the system processing the messages (possibly an MDB), extract it into a separate service class, and provide another frontend in the shape of a stateless session bean. So your service is exposed both by an sync and async interface, and the client can choose.
In your scenario your servlet just calls an EJB synchronously.
As for the problems which may happen otherwise: Have a look at JMS request/response pattern in transactional environment (this approach uses a temporary queue).
Using a single queue (the way you have quoted in your question), you need a selector (the condition) to get relevant messages: This might be slow, depending on the volume in the queue.
On the other hand, if you implement your servlet with asynchronous support as well (using #WebServlet(asyncSupported = true)), it's something different. In that case I would say it's a valid approach.
In that scenario you can save resources (namely threads; but the HTTP connections remain open), because one background thread listening on a queue can serve multiple clients. Consider this if you have performance or resource problems. Until then I suggest the synchronous way, because it is easier to implement.
The JMS Request/Reply of the EAI Patterns might fit for you.
It's well explained and there's also samples in Java:
http://www.enterpriseintegrationpatterns.com/patterns/messaging/RequestReplyJmsExample.html
I'm relatively new to Spring, and trying to queue up a set of web reqeusts on the server (in order to warm memcached). It's unclear to me how I can transfer on the current request's credentials to be used in the future web request I'm putting in the queue. I've seen a handful of scheduling solutions (TaskExecutor, ApplicationEventMultitasker, etc) but was unclear if/how they handle credentials, as that seems to be the most complicated portion of this task.
It's not possible directly. Security credentials are stored in ThreadLocal which means once the request is forwarded to another thread, credentials are lost. All you can do (which might actually be beneficial to your design) is to pass credentials directly, by wrapping them inside Callable/Runnable or whatever mechanism you use.
Suppose you have a system on the other side of a network that sends events and data that needs to be cached to some intermediate broker.
Instead of giving every component of your application that needs to be informed of such events a new subscription to the broker, I decide for performance and simplicity (the third party library that handles broker subscriptions isnt pretty) I should have only one Event Processor that subscribes to the broker and programatically fires events as it receives them to subscribed listeners provided by the components. The cached data can also be shared from this singleton. This will greatly reduce network connections.
However according to most discussions about singletons, they are always evil PERIOD unless for concurrency reasons or hardware reasons you need only one access point. This is not my situation since every component could have their own subscription and their own personal cache of data since all the data can be requested over the broker. However this could easily add 200 more network connections.
Because singletons are evil does that mean 200 more connections to a broker with 200 copies of data is better than using singleton I don't need to use? After all this slows things down quite a bit but its not game breaking, the application is still usable.
There's nothing inherently wrong with your broker client object servicing multiple clients within your process.
All the talk about singletons being evil is really about global variables being evil. A singleton becomes evil because it provides a static access point to mutable state, not because there is only one instance of it.
In that light, you might want to use dependency injection to hook it up rather than calling Broker.getInstance(). This avoids client code making the assumption that it is in fact a singleton.