
Peter Beckman wrote:
Before I start, I strongly disagree that PHP is bad for handling Asterisk dialplan logic. You want to write your business logic in code once, then reuse it. We happen to expose our business logic via a PHP API that our Perl FastAGI uses, but not everyone has the talent/ability/forethought to build it that way. The easiest way to reuse that business logic code you wrote for the website is to build libraries you can reuse elsewhere. In this case, a PHP that talks to Asterisk in an AGI sort of way (not directly).
I suppose that if the rationale were so intricately bound up in the benign and understandable motive of code re-use, that is logical and forgivable. No argument there, given that premise. There are various observations one might make about PHP runtime performance that suggest that it really doesn't work well at all outside of mod_php and should not ever be used in standalone processes, but I'll stay away from that because that really does have the tendency to degenerate into a religious debate, and your point is fundamentally sound and cogent.
First off, calling AGI(somescript.php) is awful.
It is, but most of the broken implementations I am brought in to fix do exactly ... that! :-)
We implemented it as a FastAGI script, running as a TCP service that asterisk connects to on a listening local port. It handles all of our database connections, forks new processes off for each call, and does everything we need the way we want it done, not having to add on a bunch of hacked-together scripts and modules in Asterisk.
That sounds very workable. I suppose there might be something to be said in favour of non-blocking I/O / synchronous I/O multiplexing in a unitary process versus forking a new process or thread for every call, but that only becomes a concern with very, very large amounts of call setups. The mere fact that you have a FastAGI server versus invoking local AGI puts you like 1000% ahead of people who don't. I've built many FastAGI services - whether for call routing or more esoteric business logic - in Perl as well.
Second, if you know PHP and nothing else, it is definitely easy to get it done in PHP, especially if your business logic is in neat libraries you can include and make calls to. If you call it directly via AGI(), it can and likely will hurt or kill your resources, but using it as a long running FastAGI daemon it can be managed and connections to the DB can be shared.
There is a considerable body of evidence suggesting that although PHP does expose a socket API, using it to do sockets is a terrible idea because it just doesn't perform well at all. I don't know why anyone would write a server - FastAGI or otherwise - in PHP. Besides, PHP does not really have the appropriate low-level dimension for heavyweight or nuanced system calls; that's not what it was designed for. Then again, I suppose people make that argument for Java, too. On the other hand, I have no trouble believing it still works better than local AGI() script invocations.
Last, if all of your business logic is already done in PHP for your website, it's really easy to simply re-use this existing code in your AGI. And if you do it right and well, it may even scale fairly well.
True, very true.
Your point however is still very valid: most customers do NOT do it right and well, and they should be motivated to learn how to do it better. I do think your downplay of PHP as an AGI language is simply misdirected. PHP can do FastAGI, and you can pool connections, fork processes, do things elegantly, same as with a Perl or C++ compiled FastAGI script. Of course we all know C++ will run faster, but we also know good C++ folk are hard to find, and once they build it, it's hard to find them again to update it. PHP programmers are easier to find, and if we simply educate them about how to build a FastAGI written in PHP reusing business logic already build into their website, well, it seems like a pretty good path to me.
Maybe. I suppose it's just hard for me to see, as someone with a programming background that almost entirely consists of socket-layer programming and network protocol implementation (in C), how PHP - given its architecture - can do those things in a scalable fashion even if it does bother to publish APIs for the underlying system calls. Managing large amounts of I/O-bound processing just isn't what it was built for at all. Even my curl_*() calls out of PHP are dog-slow. It's a qualitative issue -- "just because you can, doesn't mean you should." The real answer lies in robust performance studies and in the details of PHP's runtime implementation. I have neither of these annals at my ready disposal in order to illustrate that point. There's just a general principle that high-level, non-typed web languages aren't designed to participate in the same problem domain as general-purpose programming languages and/or languages on which systems are built at that lower level of abstraction. It is within the realm of conception that you could write a virtual machine container/hypervisor in PHP, if only the interpreter exposed the system calls and other primitives you'd need to pull it off. But it's not done for a reason--surely you can agree. (Except perhaps for the novelty/Slashdot factor by someone with far too much time on their hands.)
For my Perl FastAGI, I use Net::Server::Fork and Asterisk::AGI (with a few fixes and modifications) and it works great.
Interesting. I've tended to use Asterisk::FastAGI in the past, but it never seems to obey my bind port parameter on the initial invocation. -- Alex -- Alex Balashov Evariste Systems Web : http://www.evaristesys.com/ Tel : (+1) (678) 954-0670 Direct : (+1) (678) 954-0671 Mobile : (+1) (678) 237-1775