Skip to content

Instantly share code, notes, and snippets.

@andrewiggins
Last active July 27, 2020 19:12
Show Gist options
  • Save andrewiggins/8068f41fc441205e6b1506fb8186903c to your computer and use it in GitHub Desktop.
Save andrewiggins/8068f41fc441205e6b1506fb8186903c to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
// Available variables:
// - Machine
// - interpret
// - assign
// - send
// - sendParent
// - spawn
// - raise
// - actions
// - XState (all XState exports)
const randomInt = (min, max) => Math.floor(Math.random() * (max - min)) + min;
const lockConfig = {
createDelayMs: 1000, // 1s
minHoldTimeMs: 2500, // 2.5s
checkDelayMs: 500, // 0.5s
minWaitTimeMs: 1000, // 1s
maxWaitTimeMs: 3000, // 3s
waitTimeoutMs: 60 * 1000, // 1 minute
};
const lockMachine = Machine({
id: "AcquireLockMachine",
initial: "initialRead",
context: {
wait_time: 0,
total_wait_time: 0,
total_held_time: 0,
},
states: {
initialRead: {
on: {
// comment doesn't exist
CREATE: 'delayingCreate',
// comment exists, locked
ACQUIRE: 'delayingAcquire',
// comment exists, have hold
HOLD: 'holding',
// comment exists, no lock
WRITE: 'writing'
}
},
attemptingCreate: {
on: {
// comment doens't exist, done waiting
CREATE: "creating",
// comment exists, try to acquire
ACQUIRE: "acquiring",
// comment doesn't exist, need to wait
DELAY: "delayingCreate",
// wait time exceeded time out
TIMEOUT: "timed_out",
},
},
delayingCreate: {
on: {
COMPLETE_WAIT: "attemptingCreate",
},
},
creating: {
on: {
ACQUIRED: "acquired",
},
},
acquiring: {
on: {
// Comment exists, no one has lock
WRITE: "writing",
// comment exists, is locked
WAIT: "delayingAcquire",
// comment exists, wait timeout exceeded
TIMEOUT: "timed_out",
},
},
// Wait random time before attempting to acquire again
delayingAcquire: {
entry: ["resetTotalHeldTime", "setWaitTime"],
exit: "updateTotalWaitTime",
on: {
COMPLETE_WAIT: "acquiring",
},
},
writing: {
on: {
HOLD: 'holding',
},
},
// Wait deterministic time before reading lock
holding: {
entry: "resetTotalWaitTime",
exit: "updateTotalHeldTime",
on: {
CHECK_HOLD: "checking",
},
},
// read lock to see if we still have it
checking: {
on: {
ACQUIRED: "acquired",
HOLD: "holding",
WAIT: "delayingAcquire",
},
},
// final states
acquired: {
type: "final"
},
timed_out: {
type: "final"
},
},
},
{
actions: {
resetTotalHeldTime: assign({
total_held_time: 0,
}),
updateTotalHeldTime: assign({
total_held_time: (ctx, evt) => {
return ctx.total_held_time + lockConfig.checkDelayMs;
},
}),
setWaitTime: assign({
wait_time: (ctx, evt) => {
console.log(evt);
return randomInt(
lockConfig.minWaitTimeMs,
lockConfig.maxWaitTimeMs
);
},
}),
resetTotalWaitTime: assign({
total_wait_time: 0,
}),
updateTotalWaitTime: assign({
wait_time: 0,
total_wait_time: (ctx, evt) => {
return ctx.total_wait_time + ctx.wait_time;
},
}),
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment