Hacker News new | ask | show | jobs
by dividuum 2090 days ago
Is there only a single instance of the example Counter object globally and as there are no additional await'ed calls between the get and put operations, the atomicity is guaranteed? Is the object then prevented from getting instantiated on any other worker?

Can this result in a deadlock if I access DurableClass(1), then delayed DurableClass(2) in one worker and DurableClass(2) and delayed DurableClass(1) in another worker?

2 comments

Each object is essentially an Actor in the Actor Model sense. It can send messages (fetches, and responses to fetches) to other objects and regular workers. Incoming requests are not blocked while waiting for previous events to complete.

Hence, a block is only atomic if it contains no "await" statements.

In the counter example, the only thing we "await" (after initialization) is the storage put()s. Technically, then, you could imagine that the put()s could be carried out in the wrong order. But, we're able to guarantee that even though put() is an async method, the actual writes will happen in the order in which put()s were called.

(For those with a background in capability-based security: Our system is based on Cap'n Proto RPC which implements something called E-order, which makes a lot of this possible.)

* Disclaimer: At this very moment, there are some known bugs where put()s could theoretically happen out-of-order, but we'll be fixing that during the beta.

The actor model doesn't prevent "semantic" deadlocks that are caused by circular dependencies. It's kinda like reference counting which also doesn't handle cycles. In practice it doesn't matter and when it matters you have already saved enough brain cells that you can think about the tricky parts in isolation.

However, memory corruption via manual memory management and deadlocks via manual locking are commonly caused by simple and innocent programming mistakes and basically something one has to live with on a day to day basis.