What techniques/tools can be used to implement a distributed system with these requirements:
At a given time, the system can be in one of 3 states: SYNCING, COMPUTING, or IDLE.
Each node in the system can receive two instructions: sync() and compute().
A sync() instruction will be sent to all nodes at once. Upon getting a sync() instruction, if the system is IDLE, each node should sync its local cache with the database, and system state is changed to SYNCING. When all nodes finish syncing, the system state is changed to IDLE. In case of a node failure, the system state should still change to IDLE as soon as all the alive nodes finish syncing.
Upon getting a compute() instruction, if the system is not SYNCING, a node will run some computation and the system state should be changed to COMPUTING. When the computation is finished, or in case of a node failure, if no other computation is in progress, the state should change to IDLE.