This question isn't meant for a specific stack, but more of a general question.
I have a front-end application where users are able to create multiple stopwatch timers and run those timers simultaneously to keep track of their tasks. I need to sync the stopwatch data from the front-end to the back-end. What would the best way be to achieve this?
I'm looking for a solution that keeps the front-end and back-end timer attributes in sync as much as possible while consuming as few resources as possible.
I'm able to think of 2 solutions:
HTTP requests based on events and polling, for example, if the user pauses the timer, a PUT request gets sent to the back-end with the updated timer attributes. And for the timers that aren't paused, a PUT request gets sent every minute.
An issue with this is that if there are 1000 users and each of them has multiple stopwatch timers running, this will be a lot of requests.
Another issue is that if the page gets refreshed before a PUT request, then the timer information will, of course, be lost until the last put request.
Web sockets- I haven't worked with web sockets before, so I'm not sure how viable it is for my scenario. But from what I understand the timer table on the database can be updated in real-time from the front-end once a connection is established to the back-end. Currently, I'm unaware of any downsides to this. If there are any downsides to web sockets, please let me know.
In summary, I'm trying to update multiple timers from the front-end to the back-end, however, I'm not sure if web sockets or HTTP requests would be the best approach for minimizing the resources being used while also keeping the timers as accurate as possible.
I'd like to hear some opinions from other developers on which the better approach would be better, and possibly other solutions.
Does Spring Session management take care of asynchronous calls?
Say that we have multiple controllers and each one is reading/writing different session attributes. Will there be a concurrency issue as the session object is entirely written/read to/from external servers and not the attributes alone?
We are facing such an issue that the attributes set from a controller are not present in the next read... this is an intermittent issue depending on the execution of other controllers in parallel.
When we use the session object from the container we never faced this issue... assuming that it is a direct attribute set/get happening right on to the session object in the memory.
The general use case for the session is storing some user specific data. If I am understanding your context correctly, your issue describes the scenario in which a user, while for example being authenticated from two devices (for example a PC and a phone - hence withing the bounds of the same session) is hitting your backend with requests so fast you face concurrency issues around reading and writing the session data.
This is not a common (and IMHO reasonable) scenario for the session, so projects such as spring-data-redis or spring-data-gemfire won't support it out of the box.
The good news is that spring-session was built with flexibility in mind, so you could of course achieve what you want. You could implement your own version of SessionRepository and manually synchronize (for example via Redis distributed locks) the relevant methods. But, before doing that, check your design and make sure you are using session for the right data storage job.
This question is very similar in nature to your last question. And, you should read my answer to that question before reading my response/comments here.
The previous answer (and insight) posted by the anonymous user is fairly accurate.
Anytime you have a highly concurrent (Web) application/environment where many different, simultaneous HTTP requests are coming in, accessing the same HTTP session, there is always a possibility for lost updates caused by race conditions between competing concurrent HTTP requests. This is due to the very nature of a Servlet container (e.g. Apache Tomcat, or Eclipse Jetty) since each HTTP request is processed by, and in, a separate Thread.
Not only does the HTTP session object provided by the Servlet container need to be Thread-safe, but so too do all the application domain objects that your Web application puts into the HTTP session. So, be mindful of this.
In addition, most HTTP session implementations, such as Apache Tomcat's, or even Spring Session's session implementations backed by different session management providers (e.g. Spring Session Data Redis, or Spring Session Data GemFire) make extensive use of "deltas" to send only the changes (or differences) to the Session state, there by minimizing the chance of lost updates due to race conditions.
For instance, if the HTTP session currently has an attribute key/value of 1/A and HTTP request 1 (processed by Thread 1) reads the HTTP session (with only 1/A) and adds an attribute 2/B, while another concurrent HTTP request 2 (processed by Thread 2) reads the same HTTP session, by session ID (seeing the same initial session state with 1/A), and now wants to add 3/C, then as Web application developers, we expect the end result and HTTP session state to be, after request 1 & 2 in Threads 1 & 2 complete, to include attributes: [1/A, 2/B, 3/C].
However, if 2 (or even more) competing HTTP requests are both modifying say HTTP sessoin attribute 1/A and HTTP request/Thread 1 wants to set the attribute to 1/B and the competing HTTP request/Thread 2 wants to set the same attribute to 1/C then who wins?
Well, it turns out, last 1 wins, or rather, the last Thread to write the HTTP session state wins and the result could either be 1/B or 1/C, which is indeterminate and subject to the vagaries of scheduling, network latency, load, etc, etc. In fact, it is nearly impossible to reason which one will happen, much less always happen.
While our anonymous user provided some context with, say, a user using multiple devices (a Web browser and perhaps a mobile device... smart phone or tablet) concurrently, reproducing this sort of error with a single user, even multiple users would not be impossible, but very improbable.
But, if we think about this in a production context, where you might have, say, several hundred Web application instances, spread across multiple physical machines, or VMs, or container, etc, load balanced by some network load balancer/appliance, and then throw in the fact that many Web applications today are "single page apps", highly sophisticated non-dumb (no longer thin) but thick clients with JavaScript and AJAX calls, then we begin the understand that this scenario is much more likely, especially in a highly loaded Web application; think Amazon or Facebook. Not only many concurrent users, but many concurrent requests by a single user given all the dynamic, asynchronous calls that a Web application can make.
Still, as our anonymous user pointed out, this does not excuse the Web application developer from responsibly designing and coding our Web application.
In general, I would say the HTTP session should only be used to track very minimal (i.e. in quantity) and necessary information to maintain a good user experience and preserve the proper interaction between the user and the application as the user transitions through different parts or phases of the Web app, like tracking preferences or items (in a shopping cart). In general, the HTTP session should not be used to store "transactional" data. To due so is to get yourself into trouble. The HTTP session should be primarily a read heavy data structure (rather than write heavy), particularly because the HTTP session can be and most likely will be accessed from multiple Threads.
Of course, different backing data stores (like Redis, and even GemFire) provide locking mechanisms. GemFire even provides cache level transactions, which is very heavy and arguable not appropriate when processing Web interactions managed in and by an HTTP session object (not to be confused with transactions). Even locking is going to introduce serious contention and latency to the application.
Anyway, all of this is to say that you very much need to be conscious of the interactions and data access patterns, otherwise you will find yourself in hot water, so be careful, always!
Food for thought!
We are currently designing a web service based process, in which we will be using the web-service invoke and receive steps to communicate with a Microsoft biz-talk server.
Our main concern is that a task on the receive step can wait for some time (up to one week) until the biz-talk responds to us, which (we think) would incur a performance penalty on the workflow system as it will be polling for response.
My question is, is there any known performance considerations for the receive step, specially for leaving work items for extended periods?
No, I don't think there will be any undue "overhead". Yes, internally the process engine "polls". For just about anything. Including invoking components, or executing timers. But from a system perspective, you're just waiting for a request.
It sounds like a "receive" step is exactly the right solution here.
In a standalone windows application (Wpf/Winforms) I can see the benefits of using async implementation of long running methods to keep the UI responsive.
As I know, the IIS is will take care of the threading stuff e.g the web service will not block while its processing another request.
So my questions are:
When it comes to implementing a web service using async/await, does that makes sence ?
Will we gain any performance/scaling benefits for making the implementation async e.g using the async/await keywords.
To make a wcf service scale and perform well, can the only tuning be done in the config file or are there other things to think of ?
I'm interested in hearing your experiences and not only links to theoretical articles.
Thanks
Web services in general can gain a benefit from async/await if they use naturally-asynchronous operations. This is because async can return the IIS thread to the thread pool while it is waiting for the operation to complete, instead of blocking that thread.
I haven't heard many numbers on WCF services, but on the MVC/WebAPI side I've heard of scalability benefits in the 10x-100x range.
"Naturally-asynchronous" usually means "I/O-based". Obviously, there's no benefit if you just use Task.Run to offload a CPU-bound (or blocking) call onto a thread pool thread - you'd just be trading one thread for another. But if your implementation is I/O-bound, then you can use async to make maximum use of the thread pool.
Another thing to keep in mind is the scalability of the system as a whole. I.e., if your WCF calls all just turn around and call a single SQL Server backend, then you probably won't get any benefit from scaling WCF because the SQL Server will be your scalability bottleneck.
But in general, I recommend using async/await on your server-side code for any naturally-asynchronous work.
I am using a proprietary IoC mechanism in my asp.net mvc3 application (on IIS7) that saves state in [ThreadStatic] fields and therefore relies on an assumption that HttpApplication.BeginRequest, HttpApplication.EndRequest and the whole synchronous execution of the (single) request they relate to are executed on the same thread.
Is that assumption correct?
Is that assumption correct?
No, this assumption is not correct and there's evidence for it. The only reliable per request storage mechanism in ASP.NET is HttpContext.Items.
Never use [ThreadStatic] fields to store per-request values in an ASP.NET application. For example if you have an asynchronous controller you could very well have the engine draw one request from the thread pool to begin serving the request, then initiate an asynchronous operation relying on an IOCP (I/O Completion Port) and finally draw another thread from the pool to finish the request. So you could have 2 different threads serving the same HTTP request.
Absolutely never rely on the fact that the HTTP request will be served by the same thread.
This could be true in some cases for synchronous requests but remember that this is just an implementation detail. This could change without any notice from one version of .NET to another. You should never rely on it and never use [ThreadStatic] in ASP.NET. This could bite you very badly.