I would like to implement a mechanism in my server application but I'm not sure which OTL abstraction would be best appropriate.
My application collects data about various types of equipements.
Some of them use synchronous communication, thus generating Delphi event in my server application. (push-like)
Some of them use asynchronous communication, requiring my application to periodically request the latest data available. (pull like)
Because I want my server application to stay responsive while requesting as frequently as possible the new available data, I want to put that "pull driver" within a separated thread that will request all the configured data points one by one.
I'd like my main thread to spawn this OTL object and then receive the result as a delphi event in the main thread. This would emulate the "push-like" that my server main code is already made for.
Think of it as a thread you launch that periodically request a data you want to monitor and only send you an event when the value has changed.
Which OTL abstraction (high level? Low level?) do you think would be appropriate to this behavior?
Thank you.
I'm not sure OTL gives you much benefit here at all, to be honest. I write a lot of classes for managing hardware devices and the class model is almost invariably a plain TThread descendent. OTL is nice for spinning off tasks and work packages, queues, parallel calculations, etc. In this case, however, you don't want to do any of that. What you do want is a class that models your device and encapsulates the functions it can perform.
This is going to be a single worker thread dedicated to pumping reads and writes to the device. It is going to be a long-lived thread that will persist as long as the class that encapsulates the device remains alive - TThread makes sense for this. Your thread is going to be a simple loop that runs continuously, polling all the required data and flushing any write requests.
The class will also serve as a data cache for the device parameters and you will need some sort of synchronization devices (mutex, critical section, etc) to protect reads and writes to those fields through properties so again it makes sense that these sync objects also exist as class fields and that your thread and class model live together in a single entity. If you want event notifications, these too conveniently wrap into the same model. One device, one thread, one class. It's a perfect job for a TThread descendent.
Related
I have a Multi-Client Single-Server application where client and server gets connected through sockets. Client and Server are in different machine.
In client Application, client socket gets connected to server and sends data periodically to server.
In server application server socket listens for client to connect. When a client is connected, new thread is created for client to receive data.
for example: 1 client = 1 thread created by server for receiving data. If its 10000 client, server creates 10000 threads. This seems not good and scalable too.
My Application is in Java.
Is there an alternate method for this problem?
Thanks in advance
This is a typical C10K problem. There are patterns to solve this, one examples is Reactor pattern
Java NIO is another way where the incoming request can be processed in non blocking way. See a reference implementation here
Yes, you should not need a separate thread for each client. There's a good tutorial here that explains how to use await to handle asynchronous socket communication. Once you receive data over the socket you can use a fixed number of threads. The tutorial also covers techniques to handle thousands of simultaneous communications.
Unfortunately given the complexity it's not possible to post the code here, so although link-only answers are frowned upon ...
I would say it's a perfect candidate for an Erlang/Elixir application. Whatsapp, RabbitMQ...
Erlang processes are cheap and fast to start, Erlang manages the scheduling for you so you don't have to think about the number of threads, CPUs or even machines, Erlang manages garbage collection for each process after you don't need it anymore.
Haskell is slow, Erlang is fast enough for most applications that are not doing heavy calculations and even then you can use it and hand off the heavy lifting to a C process.
What are you writing in?
Yes, you can use the Actor model, with e.g. Akka or Akka.net. This allows you to create millions of actors that run on e.g. 4 threads. Erlang is a programming language that implements the actor model natively.
However, actors and non-blocking code won't do you much good if you are relying on blocking library calls for backend services that you rely on, such as (the most prominent example in the JVM world) JDBC calls.
There is also a rather interesting approach that Haskell uses, called green threads. It means that the runtime threads are very lightweight and are dynamically mapped to OS threads. It also means that you get a certain amount of scalability "for free", with no need to write non-blocking IO code. It does however require a good IO manager in the runtime to schedule the IO operations efficiently, and GHC Haskell has had a substantial amount of work put into that in recent years.
I have experience working with RxJava, to make reactive applications. However, I'm wondering how it (and other libraries, like Spring Reactor), actually work on the inside. I can't seem to find any interesting information regarding that online, only the typical simple tutorials. How does it deal with threading, etc? Do all "actors" run on the same thread? Or is it a thread per "declaration"?
One key point about RxJava is it allows both the API owner and the consumer to decide on an execution model (and change it without breaking any interfaces). If you want to expose an observable which runs on the calling subscriber thread, inside an ExecutorService, on an Actor, e.t.c, that's up to you. Likewise you can subscribe to an observable using whatever threading model suits- be it blocking on the calling thread or on some kind of thread pool. Bottom line is the library itself takes no opinion on threading model; you need to decide what's best for the workload you're exposing.
Here is my scenario:
I have two servers with a multi-threaded message queuing consumer on each (two consumers total).
I have many message types (CreateParent, CreateChild, etc.)
I am stuck with bad legacy code (creating a child will partially creates a parent. I know it is bad...But I cannot change that.)
Message ordering cannot be assume (message queuing principle!)
RabbitMQ is my message queuing broker.
My problem:
When two threads are running simultaneous (one executing a CreateParent, the other executing a CreateChild), they generate conflicts because the two threads try to create the Parent in the database (remember the legacy code!)
My initial solution:
Inside the consumer, I created an "entity locking" concept. So when the thread processes a CreateChild message for example, it locks the Child and the Parent (legacy code!!) so the CreateParent message processing can wait. I used basic .net Monitor and list of Ids to implement this concept. It works well.
My initial solution limitation:
My "entity locking" concept works well on a single consumer in a single process on a single server. But it will not works across multiple servers running multiple consumers.
I am thinking of using a shared database to "store" my entity locking concept, so each processes (and threads) could access the database to verify which entities are locked.
My question (finally!):
All this is becoming very complex and it increases the bugs risk and code maintenance problems. I really don`t like it!
Does anyone already faced this kind of problem? Are they acceptable workarounds for it?
Does anyone have an idea for a clean solution for my scenario?
Thanks!
Finally, simple solutions are always the better ones!
Instead of using all the complexity of my "entity locking" concept, I finally turn down to pre-validate all the required data and entities states before executing the request.
More precisely, instead of letting CreateChild process crashes by itself when it encounter already existing data created by the CreateParent, I fully validate that everything is okay in the databases BEFORE executing the CreateChild message.
The drawback of this solution is that the implementation of the CreateChild must be aware of what of the specific data the CreateParent will produces and verify it`s presence before starting the execution. But seriously, this is far better than locking all the stuff in cross-system!
As I've done some more research into web server software, I've begun to question if Apache's thread/process based method is the way to go vs. the the asynchronous request handling provided by servers like Nginx a Lighttpd, which tend to scale better with heavier loads.
I understand there are many other differences between these latter two and Apache. My question is under what circumstances would I pick a thread/process based method over the asynchronous handling.
Are there any features/technologies that I can't use with an asynchronous method (or would function poorly/not as well)?
What situations would cause the performance of an asynchronous method to perform worse than a thread/process based approach? Are these common or rare cases, and how big is the difference?
Are there any other factors I should take into consideration when comparing the two? Keep in mind I'm focusing mainly on the thread/process based method vs. asynchronous, not any particular server software which happens to utilize one of these methods. These concerns might be difficulty of managing/debugging, security issues, etc.
This is old, but worth answering. Let's first start by saying how each model works.
In threaded, you have a request come in to a handler, the handler spawns a new OS thread to handle that request, and all work for that request happens in that thread until a response is sent and the thread is ended. This model supports as many concurrent requests as threads that your server can spawn (but threads can be somewhat heavyweight).
When doing async a request comes in to a handler but instead of creating a thread to deal with it, it adds the connection to what's known as an event loop. The event loop listens for data/state changes on the connection and fires callbacks each time "something" happens. Once the connection is added to the event loop, the handler immediately listens for new connections to add. This allows you to have many (sometimes 100K) concurrent connections at the same time.
Are there any features/technologies that I can't use with an asynchronous method (or would function poorly/not as well)?
Yes, when you're doing number crunching. The architecture of an async (or "evented") system is such that it is great at passing data around but not processing data. It can handle thousands of concurrent operations, but because it only runs on one OS thread, the callbacks it fires need to do as little as possible to get the most throughput. This is because if one of your callbacks does some number crunching that takes 5 seconds, your entire server is frozen for 5 seconds until that operation completes. The idea is to get data, send it to where it's going (database, API, etc) and send a response all with minimal processing.
Async is good for network I/O: passing data between multiple sources/destinations (and also user interfaces, but that's beyond this post).
What situations would cause the performance of an asynchronous method to perform worse than a thread/process based approach? Are these common or rare cases, and how big is the difference?
See above, but any time you're doing more CPU work than network I/O, you should switch to a threaded model. However, there are architecture workarounds...for instance, you could have an async app, and anytime it needs to do real work, it sends a job to a worker queue. However, if every request requires CPU processing then that architecture is overkill and you might as well just use a threaded server.
Are there any other factors I should take into consideration when comparing the two? Keep in mind I'm focusing mainly on the thread/process based method vs. asynchronous, not any particular server software which happens to utilize one of these methods. These concerns might be difficulty of managing/debugging, security issues, etc.
Programming in async is generally more complicated than threaded. That said, if you're not doing the programming yourself (ie you're choosing between nginx and apache) then I usually recommend you go async (nginx) because you'll generally be able to squeeze more juice out of your server that way. I'm always in favor of using as much async in the stack as possible.
That said, if you're programming an app and trying to decide whether to use a threaded or async model, you will have to take developer time into account. Unless you're using a language that has green threads over an event loop (like scheme), expect to tear your hair out quite a bit over rogue exceptions crashing your entire app and in general wrapping your head around CPS/using callbacks for everything. Futures/promises are your friend, but are only a bandaid to make async nicer.
TL;DR
Async, when used in a server, can squeeze (a lot) more concurrent operations than threading if you're doing network IO and nothing else.
If you're doing any kind of number crunching, either use a threaded app server or use an async app with a background queuing system.
Async is a lot harder to program in unless your language supports "fake" threading over it (ie green threads). Once you get past the initial hump you're fine, generally. If you don't have green threads, use promises.
If you have the choice between threaded and async as a component in your stack (apache vs nginx), and they provide the exact same features, slightly favor async. Don't just pick it because you think it will make everything 20x faster though.
Processes have several advantages compared to threads and async models related to security and reliability. Most websites don't need these particular advantages, but sometimes they're indispensable.
Security: you can run your worker processes in a sandbox, as a low privileged user, and handle only one request per worker process. This mitigates against some kinds of security vulnerabilities: even if an attacker takes over your entire worker process, as long as you sandboxed it tightly based on request metadata (i.e. it doesn't have write access to all your data), then it can't harm system stability or affect the responses made to requests.
Security #2: sometimes you need to sandbox untrusted code, or to enforce segregation between different code or different requests, and the only way to do this is with a separate one-shot process. (Think running user-provided code.)
Reliability: memory leaks and memory corruption are much less severe if you teardown and replace worker processes regularly (or for each request).
It's easy to enforce hard limits on CPU time, disk and network quota, etc. spent on handling a user request in a separate process. Even if the request-handling code goes into an infinite loop, the master process (or the OS) can enforce a timeout.
I tend to use the following as my standard threading model, but maybe it isn't such a great model. What other suggestions do people have or do they think this is set up well? This is not for a high performance internet server, though performance is sometimes pretty critical and in those cases I use asynchronous networking methods and reuse buffers, but it is the same model.
There is a gui thread to run the gui.
There is a backend thread that handles anything that is computationally intensive (basically anything the gui can hand off that isn't pretty quick to run) and also is in charge of parsing and acting on incoming messages or gui actions.
There is one or more networking threads that take care of breaking an outgoing send into peices if necessary, recieving packets from various sockets and reassembling them into messages.
There is an intermediary static class which serves as an intermediary between the networking and backend threads. It acts as a post office. Messages that need to go out are posted to it by backend threads and networking threads check the "outbox" of this class to find messages to send and post any incoming messages in a static "inbox" this class has (regardless of the socket they arrive from, though that information is posted with the incoming message) which the backend thread checks to find messages from other machines it should act on.
The gui / backend threading interface tends to be more ad hoc and should probably have its own post office like class or some alternative intermediary?
Any comments/suggestions on this threading setup?
My primary concern is that you don't really want to lock yourself into the idea that there can only be one back-end thread. My normal model is to use the MVC at first, make sure all the data structures I use aren't inherently unsafe for a threaded environment, avoid singletons, and then profile like crazy, splitting things out as I go while trying to minimize the number of condition variables I'm leveraging. For long asynchronous tasks, I prefer to spawn a new process, particularly if it's something that might want to let the OS give it a differing priority.
This architecture sounds like the classic Model-View-Controller architecture which is usually considered as good.