News for hackers. Stuff that matters.
Re:Taking PHP Seriously by weberc2 on Thursday October 13, 2016 @06:22PM (#12704601)
The real question is why does PHP depend on globals or thread locals for request state at all? PHP's "new process per request" is a solution to a problem that PHP created for itself. In other languages, the request handler receives the request state as an argument, so when the request completes there is no state to reset.

> It seems like it would be easier for everyone involved. You wouldn't need much of a GC when the process is killed every time, you don't need to worry about async IO or multi-threading or catching errors or any of the other annoyances that come with most of the traditional "event loop" way of doing things.

Firing up a new process (or even a new thread) for each request is very expensive--much more so than a generational GC. Async IO also mitigates this (why have 10K parked threads consuming memory all your memory if all of them are stalled, waiting for database)? Services that spawn a thread for each request run into the C10K problem--they can only serve 10K simultaneous clients. Regardless of your concurrency model, you can't ignore errors--you still need to dispatch the right status codes and error information (not to mention logging, etc).

You should check out Go. You write concurrent code and the runtime effectively manages a thread pool under the covers so you get all of the performance benefits of async programming with the developer-friendliness of synchronous programming. In the case of a web app, you just need to write your request handlers--the web server manages the request concurrency for you, and the language's runtime manages the parallelism.

Re:Taking PHP Seriously by tyingq on Thursday October 13, 2016 @06:54PM (#12704833)
>>PHP's "new process per request" is a solution to a problem that PHP created for itself

True, but I'm not aware of any notable language that did it differently in the mid 1990's when PHP was rolled out. PHP does not spawn a new OS process per request these days. It does spawn a new interpreter, but not a new OS process. Combined with the now bundled opcache, the re-work per request is limited to the developer's own initialization code if they don't choose to use a user-space shared cache.

Re:Taking PHP Seriously by weberc2 on Thursday October 13, 2016 @07:14PM (#12704969)
> True, but I'm not aware of any notable language that did it differently in the mid 1990's when PHP was rolled out.

The OP's question wasn't scoped to the mid-90s.

> PHP does not spawn a new OS process per request these days. It does spawn a new interpreter, but not a new OS process.

Like I said, the same holds true even for an OS thread. Anyway, if it's not a new OS process, then some sort of GC is needed, contrary to the OP's statement.

> Combined with the now bundled opcache, the re-work per request is limited to the developer's own initialization code if they don't choose to use a user-space shared cache.

Again, these are all solutions to problems PHP invented for itself. Other languages don't require special caching mechanisms; they get by on normal scoping rules and shared memory.

Re:Taking PHP Seriously by codedokode on Thursday October 13, 2016 @07:59PM (#12705220)
I don't think so. You either keep state between requests and therefore get problems like memory leaks (which often happen in large Ruby or NodeJS apps written by not very experienced developers) or you keep no state and have to do initialization on every request.
Re:Taking PHP Seriously by weberc2 on Friday October 14, 2016 @11:05AM (#12708530)
This is only true if your framework depends on global variables to manage request state. If your framework passes request state in as an argument to the request handler, then there is no state to reset. Don't use global variables and you don't have any of these problems.
Re:Taking PHP Seriously by codedokode on Friday October 14, 2016 @01:27PM (#12709655)
How do you know whether other components (objects, modules) do not keep state between requests? Unless you 1) use language with pure stateless functions like Haskell or 2) delete everything after each request you cannot guarantee that. PHP uses latter approach.

With PHP you can see your program as a pure function whose result depends only on arguments. You don't have to care about memory leaks like you don't have to do memory management when you have a GC. And if you want more performance and less convenience you can always opt into running your own web server.

> Don't use global variables

If you have an object that is persisted between requests you already have some state that is saved.

Re:Taking PHP Seriously by weberc2 on Friday October 14, 2016 @02:10PM (#12709993)
Programming 101: scope your objects appropriately. If you have an object whose state is bound to the scope of the request handler, initialize it in that context ("don't use global vars" is just a special case of this rule). In other words, everything initialized outside your request handler's scope should have its state reused across requests. The PHP community never entirely learned this, so you guys are building workarounds. This isn't intended to be PHP bashing; just objective criticism.
Re:Taking PHP Seriously by codedokode on Friday October 14, 2016 @04:47PM (#12710984)
I do not see how scopes are related to a problem of memory leak. Let's say you have a Django middleware that is initialized outside the scope of a request. Let's say you decided to add some stats counter in that middleware and wrote a code like this:

    def __call__(self, request):
        client_ip = request.META['REMOTE_ADDR']
        self.last_visitors.append(client_ip) 
        ...
This code follows your scoping rules but still leaks memory. So it looks like you don't understand why memory leaks occur. I explained somewhere in ancestor comment that to prevent leaks you either need a language with pure functions or reset environment on each request, none of which is possible in Python yet the latter is available for PHP users.

With Django processing model any array can become the source of a memory leak. I have heard that Ruby and NodeJS developers often have to restart their applications every several hours because they even have no tools to find the source of a leak. The problem that does not exist in PHP by design.

Re:Taking PHP Seriously by weberc2 on Monday October 17, 2016 @10:05AM (#12725086)
You're conflating application state with request state. Updating application state based on a request is a perfectly reasonable thing to do, but it necessarily invites the possibility of a memory (or database, file, etc) leak. Either PHP can't update application state at all or it can and necessarily suffers from the same potential to leak memory (I suspect the latter, since an application without side-effects would be worthless).
Re:Taking PHP Seriously by Klathmon on Thursday October 13, 2016 @07:28PM (#12705050)
To clarify, I didn't say that no GC would be needed, just that it can be much less robust, use quicker algorithms, and in many cases is simpler to actually implement.
Re:Taking PHP Seriously by weberc2 on Friday October 14, 2016 @11:13AM (#12708597)
This isn't true. A shared memory server doesn't require special, complex garbage collection algorithms--any generational GC will due, because request state lives in the youngest generation where collection is virtually free.