Runtime Converter JNI Updates - Process Forks
At Runtime Converter, we have been working on an update to our JNI library that will significantly increase the reliability and security of applications using our runtime library to access PHP functions. Right now, we are loading a version of PHP into the same process-space as Java. There are two problems with this. First is that even a small bug in PHP or our code interacting with PHP will cause the server to crash. The second problem is that PHP itself is less reliable when used in a multi-threaded environment.
PHP was designed at the start to be single-threaded, and afterwards they added the ZTS ("Zend thread support") build time option. In order support threads, they had to go over most of their global variables and make them no longer global variables, but thread-based variables. This involves preprocessor macros that build one way for ZTS and another without it. Sounds easy enough, but the build flag "--enable-maintainer-zts" is still labled as experimental - "Enable thread safety - for code maintainers only!!". What that means, effectively, is that PHP has a ZTS version that they only run for the purpose of having it. It is effectively beta-release software that will never be released.
When load-testing the Runtime Converter with hundreds of requests per second with the tool JMeter, we found that above a certain number of request per-second, a segmentation fault inside of PHP would cause the server to crash. This is obviously not an acceptable outcome, as even if it was used on a small site, the uncertaintly would be a problem.
When PHP is run as single-threaded, the server loads several PHP processes and uses one process per request. When the request is over, it clears all the data assosiated with the request. If PHP were to crash with the non-ZTS version then it will not take out the entire server. The request will fail, but ongoing requests will not be interfered with because each has their own unique PHP process.
At Runtime Converter, we are developing the next version of the JNI library along this model, using forked processes, shared memory, and semaphores. The advantage here is both that PHP should crash less or not at all, and that even if it does, it will not affect the Java JVM. There is also an additional security benefit - code in the sub-process does not have access to the parent process (however ultimately trivial). Also, if PHP code uses extensions with memory leaks, we can in theory support this as well by cycling the processes.
It is not clear yet how this will affect the runtime performance of the library, but it is a necessary step. It also makes use of the work done on protobuffers to establish the binary fornat for inter-process communication.