Basically, actions are high-level request handlers, whether the request is initiated from a web browser, the command line, or an action API hit. Browsing the admin interface, running events from cron, and pushing products to a slave ModernBill are actions.
Commands which merely wrap around database access.
Commands which manipulate data in a complicated way, triggered by user input.
ModernBill's automation involves "events", which ultimately trigger MBAPI process commands which either do time-specific data processes, like generating invoices, or hit remote APIs.
Commands which provide common, system-local interfaces to remote interfaces.
To understand system portability problems, the techniques these concepts use to interact with the underlying system need to be known. The rest of this section will discuss these interactions.
Most web platforms, including PHP, execute a program for each HTTP request. No program state is persisted between requests. This is called the "stateless" model. The benefit of stateless programming is that the resources required scale lineally with the amount of requests. It is easy to scale by "throwing more hardware at the problem". The drawback is that all session-oriented objects need to be reconstructed for each request, so the higher the session overhead, the more latency occurs, no matter how many resources you have available because the latency is limited to the speed of whichever resource is being used.
ModernBill has a very high session overhead, so a common complaint is high latency. One way to deal with this session latency is to reduce how often sessions need to be initialized, changing the model from "stateless" to "stateful". In the stateful model, requests are separated from sessions so that session instances can be kept initialized to allow multiple requests to be handled with the same session instance. The session latency only occurs when the session is created, at login.
The stateful model changes the performance characteristics so that the number and size of concurrent sessions are a factor, so the more requests per session, the higher the session overhead, the more performance benefits, as long as there is enough system memory to deal with the lingering sessions. If there is a lot of time between requests, and a lot of lingering sessions, system memory can be exhausted, but lowering the session timeout alleviates that problem.
ModernBill has several modes of operation:
This is the usual model where the session is reconstructed for each request.
All state, per request, is reinitialized at the beginning and destroyed at the end.
Requires nothing special.
ModernBill has experimental support for caching large pre-initialized components of sessions in shared memory. Since locales are often shared by sessions, and since the locale information is such a large component of sessions, it makes sense to cache the initialized locale objects. Nearly half of the session overhead is removed when this is done.
Most state, per request, is reinitialized at the beginning and destroyed at the end, but some is cached in system memory in its initialized state and is copied back into each request process as needed.
Requires the sysvshm and sysvsem PHP extensions; only available on Unix systems.
ModernBill has highly experimental support for a stateful execution model. Currently, it is implemented by spawning a daemon session server on login.
All state, per session, subject to a timeout, is reinitialized at the beginning and destroyed at the end. Each request process merely serializes the request and response between the session server. Instead of copying part of the session, the request and response are copied.
Requires the posix and pcntl PHP extensions, and a PHP SAPI that supports fork(2) and setsid(2), like cgi; only available on Unix systems.
/lib-action/baseaction.php.phpdispatchAction() function./lib-tk/include/io/ipc.phpsysvsem, sysvshm, and sysvmsg PHP extensions; used by the semi-stateful method./lib-tk/include/sessionServer/sessionServer.php/app-*/path.php/lib-tk/daemon.phpdaemonize() function used to spawn session servers.The way ModernBill executes background processes is dependent upon the PHP SAPI which dispatches the automation process. Ideally, ModernBill's background processes need to be able to run unfettered. Many processes are unable to recover from being killed while processing. For example, between the time when a remote API call is requested and when it returns. If ModernBill is subject to being killed mid-process by a web server script timeout, problems will likely occur over time.
At the back-end, all automation is performed by the ProcessSystemQueue MBAPI command. At the front-end, virtually all automation is initiated by the same internal action in ModernBill called RunEvents. The only exception is when an event is "Debug Run", in which case the internal action RunDebugEvent is called. RunDebugEvent is always called from a web server request, and just runs ProcessSystemQueue within that same request's execution environment. However, RunEvents recursively spawns execution environments as needed until all events are run.
RunEvents can spawn an execution environment in three different ways, and can be dispatched in two different ways:
RunEvents can be dispatched/app-modernbill-admin/sbin/runevents.php command-line script.RunEvents can spawn execution environmentsfsockopen() or cURL to do an HTTP request to RunEvents which handles a batch of events. When a batch of events is finished, it will recursively hit itself until all events are run. This is a hack, and is the most unreliable method. This method can be used both ways RunEvents can be dispatched.shell_exec() to execute RunEvents which handles all events remaining to be run. This method can be used only when RunEvents is dispatched from the command-line. This method is very reliable.fork(2) and setsid(2) to spawn a daemon process which handles all events remaining to be run. This method can be used both ways RunEvents can be dispatched, but depends on obscure features of PHP which are rarely available, and only works when the web server handles PHP using the CGI PHP SAPI. This method is very reliable, and is the only reliable method that works in both dispatch methods./app-modernbill-admin/sbin/runevents.phpRunEvents action, for running events on cron./app-modernbill-admin/sbin/runevents.shrunevents.php to help with debugging./app-modernbill-admin/include/lib-action/events/RunEvents.phpRunEvents action. This contains the logic for running a batch of events./app-modernbill-admin/include/lib-action/events/RunDebugEvent.phpRunDebugEvent action./lib-tk/persist.phpRunEvents./lib-tk/daemon.php/lib-modernbill/include/lib-mbapi/ProcessSystemQueue.phpPlease see the article on ModernBill's Networking Libraries.