Since we wrote our own pushpool replacement, we did all the scoring calculations there. You are correct, PHP wouldn't be the place to do them. Neither is SQL though. To do it right you'll want to do it in your pool backend, which is pushpool I'm assuming? You'll want to keep the shares in memory, and do your scoring computations off of the in-memory copy.
I'm a little unclear on how you'd achieve keeping the scoring information in memory in a long round without taking up an extraordinary amount of memory? But regardless, how do you pass that information off to a web browser looking for it? Additionally, how do you handle (or do you not) multiple getwork servers? Each one would have differing information.
I do not know much about your backend, but it sounds like we are two entirely different architectures. On my pool we use Redis (a no-SQL datastore) and Node.js. Additionally we have a single "getwork server". So, since Redis stores everything in memory anyway, we were able to really quickly re-perform the scoring algorithm on every share submission. Unless you centralize your share data in someplace other than SQL, I do not think our solution will be easy for you.
I am curious, why do you have multiple servers? Is it to allow for users to be closer to a server (e.g., geographic distribution), or are you doing this for performance reasons? If at all possible try and consolidate your getworks to a single server, and I think that will open up more possibilities to you.
I read the linked post in regards to how ESMPPS works and I'm a little confused - it seems like unless you have a large run of good luck, the pool will always run in the red and be behind in paying out shares? As time goes on, the pool would go further and further into the red. Does ESMPPS count on a run of good luck to even things out?
I am not aware of any single post that fully describes ESMPPS, unfortunately. I'd love to write one, but I've just been pretty swamped lately.
ESMPPS does not depend on luck to even things out. In fact, that is one of the key differences between it and SMPPS. SMPPS pays out older shares first. So, if the pool gets behind on payment, then it neglects newer shares to pay back older shares. This creates a problem where new miners may have to wait several rounds without any payment before receiving any of their earnings. Obviously nobody wants to work for "free", so it would be a very disastrous thing for a SMPPS pool to go red.
ESMPPS solves this problem by putting all shares into "buckets", allocated by their percent paid. A bucket is never paid more (percentage wise) than the least paid bucket. This allows for all shares to be paid the maximum amount possible, while not favoring older or new miners.
Take the scenario where a pool is always lucky. The pool would therefore always have a positive buffer, and therefore pay 100% of what a 0% "true" PPS would. However, you and I both realize two problems with this scenario. A, no pool will ever be lucky 100% of the time. And B, no "true" PPS can sustain a 0% fee.
So, let's look a a difference scenario. Say you pay out on invalid blocks, and have a 0.5% block withholder rate (e.g., 0.5% of your pools hashing power is "attacking" you by withholding any block solutions they may find). Assume the probability of a block becoming invalid is ~1%. Also, assume that "luck" nets out to 0 over a long period of time.
In this scenario, you will eventually reach a future where no bucket is paid past the 98.5% bucket. However, unlike *MPPS systems old and new shares are paid immediately up to the 98.5% range. This underpayment is remembered by the system, and if the buffer goes positive, the backpay is made up. Interestingly enough, even in this scenario the ESMPPS pool still behaves "normal" and outperforms any true PPS pool, provided that true PPS pool charges more than a 1.5% fee.
IMHO it's a pretty interesting dynamic, a pool that "self regulates" itself. This is, ideally, what a true PPS pool tries to accomplish when the pool operator charges a fee. However, in the case of ESMPPS it set by the probabilities of the situation itself, and if the situation takes a turn for the better then everybody wins. If the situation stays the same, it still outperforms true PPS.