Grid Ops Java - Overview
Grid Ops is designed for distributed systems architecture experimentation. The core of distributed systems is communication between nodes over a network. Therefore Grid Ops is designed to make this communication easy.
Basically, Grid Ops is designed to implement client / server communication in a variety of configurations, whether as a pure client, a pure server, a P2P node (both client and server). Furthermore, Grid Ops is designed to support clients and servers in both passive and active mode, blocking and non-blocking mode, and push and pull modes. We will see how all this looks and works in this document.
Passive vs. Active mode
As mentioned earlier, Grid Ops supports both an passive and active mode of operation.
In passive mode, Grid Ops does not do anything until the application using Grid Ops calls a Grid Ops API. Passive mode is useful in desktop applications where Grid Ops is used internally to implement a client that connects to a Grid Ops server somewhere, but only when the user of the application takes action.
In active mode, Grid Ops is typically "managed" by one or more independent threads that each execute a thread loop. The thread loop keeps iterating until the thread loops is requested to shut down. Thread loops are useful for implementing servers that need to check for incoming messages continuously.
Blocking vs. Non-blocking Mode
Grid Ops's client and server can operate both in blocking and non-blocking mode. In blocking mode, the API calls block until the IO operation is finished. For instance, until a message is fully received, or a message is fully sent.
Blocking mode tends to work best with passive mode, where the Grid Ops API's are called from another thread that is not a thread loop specific thread. Especially in situations where the calling thread cannot really do anything else sensible than wait for the IO API call to finish.
In non-blocking mode the IO API calls return immediately. If a message was partially received, you will have to call again later, to check if the full message is then received. If a message was partially sent, you will have to call again later, to make sure the rest of the message gets sent.
Non-blocking mode typically works best with active mode, where a thread loop is continuously checking for new incoming messages, and continuously checking if all outbound messages have been sent.
Push vs. Pull Mode
Grid Ops is designed to let you use Grid Ops in either push or pull mode.
Push mode is the mode you are used to from the Java Servlet API, or other reactive frameworks like Netty, Vert.x etc. When a message is received, it is pushed into the component registered to handle this message. This is how a Servlet works. When an HTTP request arrives, it is pushed into the Servlet registered to handle requests matching the given URL.
Pull mode is when Grid Ops does not read incoming messages or write outgoing messages, until you tell it to. You pull new message out of Grid Ops APIs when you are ready to process them.
As you have probably figured out, push mode is typically paired with active mode, and pull mode is typically paired with passive mode. However, underneath the surface, even the active / push mode uses pull mode to first pull message out of the core APIs, before they are pushed into the components registered to handle them.
In active mode, Grid Ops components are managed by one or more threads executing a thread loop each. Grid Ops comes with different thread loop implementations, each of which are designed for specific situation or use case. You can also implement your own thread loops, but you will have to do a lot of internal Grid Ops component maintenance to get your thread loop to behave correctly.
Thread loops are typically used to manage servers. The thread loop keeps iterating, and for each iteration it looks for new inbound messages, processes them if any, and checks for outbound messages that are not fully sent.
Thread Loop Actors
Instead of implementing your own thread loop, you can just implement a thread loop actor, and plug it into a thread loop. Thread loop actors are typically called once for each iteration of the thread loop.
Some thread loops enable thread loop actors to take a pause. The thread loop actor simply tells how long time it should be paused until it should be called the next time. If all thread loop actors request a pause, the thread loop can sleep until the first thread loop actor needs to be called next. This frees up the CPU for other tasks on the computer, instead of constantly iterating in the thread loop with nothing to do.