Yeah back account may have been a bad example, but still solvable:
You can use MySQL's SELECT FOR UPDATE (not currently implemented in graphp) to do this transaction safely.
Alternatively, within the framework you can do the reserve amount as a time stamped node and connect it to the user. Then you query for reserve nodes and process them in order.
1) I like the RAM idea and in general more storage adapters. I hadn't really thought of local storage, but it makes sense for super simple prototyping.
2) I want to add DB profiling at some point (right now Libphutil does this for me at a query level, but I want to do it at a graph abstraction level). History could presumably be similar to a permanent profiler.
I think constraints vs flexibility is always a tradeoff. The main benefit of this model is very rapid prototyping where design decisions can be changed or reversed with minimum effort.
In general it scaled pretty well if you avoided loading tens of thousands of edges in a single call. A similar system was used on an app that would try to find connection strength between people using sent emails as signal. At it's peak the node table had tens of millions of rows, with some of the nodes (users) having thousands of edges each. The main pitfalls are
* loading too many edges (10K+) and associated nodes will be slow.
* Traversing nodes in a meaningful way can be difficult.
To solve these, the schema has the following indices:
On edge table: (`from_node_id`,`type`,`updated`)
On node_data table: (`type`,`data`(128))
Since edges rarely change, the first index allows you to paginate over edges by using updated as the order. As long as you request a reasonable number of edges, things should work OK. The second index is needed to get a node given some data, but a secondary use is sorting. By precomputing some score and saving it in node_data you can traverse nodes in that order (this is not currently built but is simple to do in SQL).
All this being said, the schema is pretty index heavy so if MySQL is forced to kick some of those out of memory it may lead to a bad time.
Thanks for the kind words on the model, I never thought about it being separate, but it makes 100% sense.
What I meant by that is the joins happen explicitly in code (as opposed to implicitly in queries). I got burned using another framework where my lack of knowledge of how the ORM managed DB queries would lead to really inefficient stuff - basically really bad joins that I could have avoided if I knew what the framework would do.
When I say no magic, what I mean is how you can understand what data is being loaded every step of the way so the mistake I mentioned previously is harder to make.
Also, I wanted to avoid query joins for easy sharding (if needed), but that adds an extra round trip so if needed the developer can write their own joins (giving up a bit of flexibility in the process).
Volume might be lower in BTC, but it's going up in pretty much any other currency, and since prices are mostly pegged to non-BTC currency, it makes sense that BTC transaction volume drops as the currency appreciates (you can buy goods using less BTC).
Also, while big % changes makes people shout bubble, they clearly are not looking at BTC in the same way early adopters and speculators are. BTC is not stock (which can look like a bubble if its up 100% in short period of time) it is closer to a newer better version of gold that only 0.00001% of the population owns. People excited about BTC are thinking about what happens if 1% of the population owned BTCs.
Bitcoin might fail (sometimes better technologies do), but it is clearly a big improvement over current currencies and that's pretty exciting.
The main reason I use Uber is because they always have a car available within 5 minutes in SF. If I want cheap I'll call a cab and wait 20 minutes and then call again when they don't show up.
Uber has always been about convenience over price. What other company says "I will disrupt industry X by charging twice the price". Here all they are doing is keeping with the same mission, make sure you can get an Uber as quickly as possible.
I'm for smart regulation, and I certainly agree with price gouging regulation in emergencies, but market pricing is not price gouging.
You can use MySQL's SELECT FOR UPDATE (not currently implemented in graphp) to do this transaction safely.
Alternatively, within the framework you can do the reserve amount as a time stamped node and connect it to the user. Then you query for reserve nodes and process them in order.