executing linux programs repeatedly through multi-user webpages without crashing - php

I'm working on a hardware project that (currently) uses the Beaglebone Black (eventually custom hardware will be used), and am attempting to set up a webpage on its web server that returns the status of all four leds, live, in a loop. And I want this webpage to be able to be accessed by multiple people simultaneously.
I've got the webpage updating the values of the leds live, but the problem is that if two instances of the webpage are open, they start to behave weird and eventually crash.
The webpage uses a jquery timer that executes every 10ms.
<script>
var Timer=setInterval(function(){GetLed()}, 10);
function GetLed()
{
$("#div1").load("getled3.php");
}
</script>
getled3.php uses php to execute 4 linux commands (but these might eventually be C++ programs in the future as we expand the capability of the webpage), and prints the results:
<?php
exec("cat /sys/class/leds/beaglebone:green:usr0/brightness", $Led0);
exec("cat /sys/class/leds/beaglebone:green:usr1/brightness", $Led1);
exec("cat /sys/class/leds/beaglebone:green:usr2/brightness", $Led2);
exec("cat /sys/class/leds/beaglebone:green:usr3/brightness", $Led3);
print($Led0[0] . ", " . $Led1[0] . ", " . $Led2[0] . ", " . $Led3[0]);
?>
I'm willing to do my own research into how to create a web application that plays nicely with multiple users, but so far, my searches haven't turned up any useful results, which could just be my wording.
If anyone could just post some links that would point me in the right direction for creating a web application that controls hardware, that would be most helpful, as the eventual implementation will be extremely complex, and might include the hardware running a "master" application on a loop, with the web page providing the user the ability to alter hardware set up.
I guess the best example of something like what we're doing would be a dynamic router set up page.
Thanks in advance. I'm going to keep searching in the meantime.
Edit: (with responses to comments)
I was looking to see if there was a standard way of doing this, or at least a best-practice. The end product will eventually allow the user to change settings on the hardware, force the hardware to send information to other hardware, read information about the hardware and other hardware attached to the beaglebone black. It'll eventually get quite expansive, and so what I really need is a resource (perhaps a book) where I can read about how this sort of thing is usually done.
The whole thing will eventually incorporate PWMs, GPIOs, ADCs, etc.
As for the method of accessing the leds, I understand "exec cat" isn't the best way to get that information.
I have since changed the entire set up so that now, when the beaglebone black boots, it loads a c++ program that runs in a loop, and writes files with hardware information.
Then, the webpage calls that were originally running "exec cat" are now just loading the program's output file into the browser. This solved the crashing problem, but just doesn't feel like the correct method of doing this project, because there would be a ton of files with information in them about the ADC values, the PWM values, etc. To further convolute things, the file accesses would really need a mutex to prevent the c++ program from writing a file while the web program was reading it, and a mutex to prevent the web program from reading a file if the c++ program were currently writing it. That would make 3 files per process.

A way can be to build a shell script that sets a local variable with the leds states. Then you put this script as a cron job (that is launched every 10ms or whatever you want).
After you only need to obtain the value of the local variable.

Related

max_execution_time Alternative

So here's the lowdown:
The client i'm developing for is on HostGator, which has limited their max_execution_time to 30 seconds and it cannot be overridden (I've tried and confirmed it cannot be via their support and wiki)
What I'm have the code doing is take an uploaded file and...
loop though the xml
get all feed download links within the file
download each xml file
individually loop though each xml array of each file and insert the information of each item into the database based on where they are from (i.e. the filename)
Now is there any way I can queue this somehow or split the workload into multiple files possibly? I know the code works flawlessly and checks to see if each item exists before inserting it but I'm stuck getting around the execution_limit.
Any suggestions are appreciated, let me know if you have any questions!
The timelimit is in effect only when executing PHP scripts through a webserver, if you execute the script from CLI or as a background process, it should work fine.
Note that executing an external script is somewhat dangerous if you are not careful enough, but it's a valid option.
Check the following resources:
Process Control Extensions
And specifically:
pcntl-exec
pcntl-fork
Did you know you can trick the max_execution_time by registering a shutdown handler? Within that code you can run for another 30 seconds ;-)
Okay, now for something more useful.
You can add a small queue table in your database to keep track of where you are in case the script dies mid-way.
After getting all the download links, you add those to the table
Then you download one file and process it; when you're done, you check them off (delete from) from the queue
Upon each run you check if there's still work left in the queue
For this to work you need to request that URL a few times; perhaps use JavaScript to keep reloading until the work is done?
I am in such a situation. My approach is similar to Jack's
accept that execution time limit will simply be there
design the application to cope with sudden exit (look into register_shutdown_function)
identify all time-demanding parts of the process
continuously save progress of the process
modify your components so that they are able to start from arbitrary point, e.g. a position in a XML file or continue downloading your to-be-fetched list of XML links
For the task I made two modules, Import for the actual processing; TaskManagement for dealing with these tasks.
For invoking TaskManager I use CRON, now this depends on what webhosting offers you, if it's enough. There's also a WebCron.
Jack's JavaScript method's advantage is that it only adds requests if needed. If there are no tasks to be executed, the script runtime will be very short and perhaps overstated*, but still. The downsides are it requires user to wait the whole time, not to close the tab/browser, JS support etc.
*) Likely much less demanding than 1 click of 1 user in such moment
Then of course look into performance improvements, caching, skipping what's not needed/hasn't changed etc.

Creating a long TCPDF document without timeout (so long running php process)

I'm building a feature of a site that will generate a PDF (using TCPDF) into a booklet of 500+ pages. The layout is very simple but just due to the number of records I think it qualifies as a "long running php process". This will only need to be done a handful of times per year and if I could just have it run in the background and email the admin when done, that would be perfect. Considered Cron but it is a user-generated type of feature.
What can I do to keep my PDF rendering for as long as it takes? I am "good" with PHP but not so much with *nix. Even a tutorial link would be helpful.
Honestly you should avoid doing this entirely from a scalability perspective. I'd use a database table to "schedule" the job with the parameters, have a script that is continuously checking this table. Then use JavaScript to poll your application for the file to be "ready", when the file is ready then let the JavaScript pull down the file to the client.
It will be incredibly hard to maintain/troubleshoot this process while you're wondering why is my web server so slow all of a sudden. Apache doesn't make it easy to determine what process is eating up what CPU.
Also by using a database you can do things like limit the number of concurrent threads, or even provide faster rendering time by letting multiple processes render each PDF page and then re-assemble them together with yet another process... etc.
Good luck!
What you need is to change the allowed maximum execution time for PHP scripts. You can do that by several means from the script itself (you should prefer this if it would work) or by changing php.ini.
BEWARE - Changing execution time might seriously lower the performance of your server. A script is allowed to run only a certain time (30sec by default) before it is terminated by the parser. This helps prevent poorly written scripts from tying up the server. You should exactly know what you are doing before you do this.
You can find some more info about:
setting max-execution-time in php.ini here http://www.php.net/manual/en/info.configuration.php#ini.max-execution-time
limiting the maximum execution time by set_time_limit() here http://php.net/manual/en/function.set-time-limit.php
PS: This should work if you use PHP to generate the PDF. It will not work if you use some stuff outside of the script (called by exec(), system() and similar).
This question is already answered, but as a result of other questions / answers here, here is what I did and it worked great: (I did the same thing using pdftk, but on a smaller scale!)
I put the following code in an iframe:
set_time_limit(0); // ignore php timeout
//ignore_user_abort(true); // optional- keep on going even if user pulls the plug*
while(ob_get_level())ob_end_clean();// remove output buffers
ob_implicit_flush(true);
This avoided the page load timeout. You might want to put a countdown or progress bar on the parent page. I originally had the iframe issuing progress updates back to the parent, but browser updates broke that.

How to measure speed of php scripts independantly of eachother? Various Methods?

On my website various php codes run from various programmers from whom I have bought project scripts. Some use a session ( session start etc...)
Some use external include php files and do their math within there and return or echo some things. Some run only when asked to, like the search script.
Is there an easy way for me to monitor, temporary, all the various scripts's their delays in millisecond sothat I can see whats going on below the water?
I have seen once a programmer making something and below the page there were these long listst of sentences and various ms numbers etc.
Q1. Is there a default php function for this? How do I call/toggle this?
Q2. What are the various methods with which such calculations are made?
Q3. How reliable are they? are those milliseconds theory or actual real world result?
Thanks for your insight!
Sam
No defualt method i can thnik of. But its easy.At the start of your script simply place this:
$s = microtime(true);
and at the end
$e = microtime(true);
echo round($e - $s, 2) . " Sec";
Normally you would leave the second parameter of round() as it is, but if you find that your script reports the time as ’0 Sec’ increase the number until you get an answer.check this for more
If you're running an Apache webserver, then you should have the apache benchmarking tool that can give some very accurate information about script timings, even simulating numbers of concurrent users.
From a web browser, the Firebug extension of Firefox can also be useful as a tool for seeing how long your own requests take.
Neither of these methods is purely a timer for the PHP code though
The easiest/fastest way is to install a debugging extension that supports profiling, like XDebug. You can then run a profiling tool (e.g.: KCachegrind) to profile your scripts, graph the results, and figure out what uses the most memory, execution time, etc.
It also provides various other functionalities like stack tracing, etc.

What are the advantages/disadvantages of monolithic PHP coding versus small specialized php scripts?

I have historically used a monolithic approach to PHP coding.
That is, I write one index.php, with an average size of 70k-250k, and use
mod_rewrite
to turn the rest of the
REQUEST_URI
into parameters passed into the index.php to control what is happening.
The alternative would be to write many small php scripts, each specialized to a particular purpose. I'm thinking that some of my more active ajax scripts may benefit from this.
One thing that has kept me in this thought process is I don't know how using includes, especially conditional includes would affect the performance of the opcode cache.
I have generally avoided includes altogether if possible due to my paranoia about this, but this results in either duplicating code, or staying monolithic.
As I'm using mod_rewrite anyway, converting between the two methodologies should be simple.
I look forward to your comments.
EDIT: One of my target apps currently handles 80-100 page hits per second (I got some decent hardware). Most of those are ajax requests. Everything works and is snappy, but I've developed as a php programmer without critique and need it.
Modular code is easier to understand and maintain. A huge monolithic codebase can become like a house of cards. It works just fine in practice, but changing any of the lower elements becomes impossible. If you split up your code into clear abstractions, it can be much easier to make changes and you'll save yourself a nightmare if you ever add developers.
The performance bonuses of not using included files is far outweighed by the ease of maintaining and debugging a large application using included files.
Rework is waste. Copying and pasting code from one app to another is maintenance hell.
In addition to the other comments (with which I agree completely), another view: I have made the experience that a monolithic approach, if driven to extremes, costs valuable RAM - the whole file has to be loaded to be interpreted, no matter whether everything from it is needed or not, and that alone eats off a lot from the 8, 16, or 32 MB you get per instance.
Please don't forget about testing and maintaining the code. I can't image if you're able to write unit-tests to a project which is just in single file. Futher more, it's much harded to predict which functionality can be broken by changes you've just made. In case of modular architecture if you change some module then you can only break this module and modules which depends on it. Even a small changes can be fatal to single file projects (you can forget to close quote which will break all pages at once). I think you must retest all the functionality after even small changes we've made. And this can be a pain for testers ecpecialy you're not able to use unit-tests.
Also if all code i stored in a single file then you'll more likely have a bad code. Such code will tend you to use global variables. In this case it's hard to reuse such code in other project. Of cause you can copy it, but remember when you copy something you copy all its bugs. Just imagane the project where you can use set of well-tested (tell thanks to unit-tests) libraries. When new bug appear then it's just fixed in a single place.
One more thing, when you're working in a team using a single file will be pain. Even if there is only 2 developers they waste much time to merge changes.
Any way, if your project is not big at all you can use single file appoch.
For Unix command line scripting, the monolithic approach allow a very high level of portability.
Using a single (hashbang) script even allow to dump the script in usr/bin
sudo cp myprog /usr/bin
/* (...) */
sudo cp myprog /usr/games
/* (...) */
This allow to call the program from anywhere, any path, by just typing myprog, instead of /PATH/./myprog. Make sure it can be trusted!
We have to take an extra care of the paths.
Some simple examples about paths:
/* Create a folder in the home directory, named as the script name, if not existing. -*/
if (!is_dir($_SERVER["HOME"]."/".$_SERVER["SCRIPT_NAME"])){
#mkdir($_SERVER["HOME"]."/".$_SERVER["SCRIPT_NAME"]);
}
/* Program folder path: --------------------------------------------------------------*/
$PATH = $_SERVER["HOME"]."/".basename($_SERVER["SCRIPT_NAME"])."/";
/* Program running path, currently: --------------------------------------------------------------*/
$JOBPATH = getcwd();
Handle POSIX SIGNALS
/* Register cleaning actions at SIGINT ------------------------------------- */
function shutdown() {
// Perform actions at ctrl+c
echo "Good bye!";
exit;
}
/* Register resize at SIGWINCH ---------------------------------------------- */
function consoleResize() {
#ob_start;
$W = (int)exec("tput cols"); // Columns count
$H = (int)exec("tput lines"); // Lines count
#ob_end_clean();
// Shell window terminal resized!
}
/* Register action at SIGSTOP (Ctrl + z) ---------------------------------------------- */
function sigSTOP() {
// Program paused!
}
/* Register action at SIGCONT (Type fg to resume) ---------------------------------------------- */
function sigCONT() {
// Program restarted!
}
register_shutdown_function("shutdown");
declare(ticks = 1);
pcntl_signal(SIGINT, "shutdown");
pcntl_signal(SIGWINCH, "consoleResize");
This doesn't mean we have to write everything in one block, but merge the rendering in one file allow many extra capabilities in a unix env.
There is a lot to say, php as cli script is an amazing beast.

Execute code after HTTP request is complete in PHP?

PHP provides a mechanism to register a shutdown function:
register_shutdown_function('shutdown_func');
The problem is that in the recent versions of PHP, this function is still executed DURING the request.
I have a platform (in Zend Framework if that matters) where any piece of code throughout the request can register an entry to be logged into the database. Rather than have tons of individual insert statements throughout the request, slowing the page down, I queue them up to be insert at the end of the request. I would like to be able to do this after the HTTP request is complete with the user so the length of time to log or do any other cleanup tasks doesn't affect the user's perceived load time of the page.
Is there a built in method in PHP to do this? Or do I need to configure some kind of shared memory space scheme with an external process and signal that process to do the logging?
If you're really concerned about the insert times of MySQL, you're probably addressing the symptoms and not the cause.
For instance, if your PHP/Apache process is executing after the user gets their HTML, your PHP/Apache process is still locked into that request. Since it's busy, if another request comes along, Apache has to fork another thread, dedicate more memory to it, open additional database connections, etc.
If you're running into performance problems, you need to remove heavy lifting from your PHP/Apache execution. If you have a lot of cleanup tasks going on, you're burning precious Apache processes.
I would consider logging your entries to a file and have a crontab load these into your database out of band. If you have other heavy duty tasks, use a queuing/job processing system to do the work out of band.
Aside from register_shutdown_function() there aren't built in methods for determining when a script has exited. However, the Zend Framework has several hooks for running code at specific points in the dispatch process.
For your requirements the most relevant would be the action controller's post-dispatch hook which takes place just after an action has been dispatched, and the dispatchLoopShutdown event for the controller plugin broker.
You should read the manual to determine which will be a better fit for you.
EDIT: I guess I didn't understand completely. From those hooks you could fork the current process in some form or another.
PHP has several ways to fork processes as you can read in the manual under program execution. I would suggest going over the pcntl extension - read this blog post to see an example of forking child processes to run in the background.
The comments on this random guy's blog sound similar to what you want. If that header trick doesn't work, one of the comments on that blog suggests exec()ing to a separate PHP script to run in the background, if your Web host's configuration allows such a thing.
This might be a little hackish for your taste, but it would be an effective and simple workaround.
You could create a "queue" managed by your DB of choice, and first, store the request in your queue table in the database, then output an iframe that leads to a script that will trigger the instructions that match up with the queue_id in your database.
ex:
<?php
mysql_query('INSERT INTO queue ('instructions') VALUES ('something would go here');
echo('<iframe src="/yourapp/execute_queue/id?' . mysql_insert_id() . '" />');
?>
and the frame would do something like
ex:
<?php
$result = mysql_query('SELECT instructions FROM queue WHERE id = ' . $_GET['id']);
// From here, simply execute some instruction based on the "instructions" field, then delete the instruction from the database.
?>
Like I said, I can see how you could consider this hackish, but the frame will load independent of its parent page, so it would achieve what you want without running some other app in the background.
Hope this at least points you in the right direction.
Cheers!

Categories