Last active
September 18, 2019 18:27
-
-
Save matthamil/6bb448100cb1d3f4275bca5be923377e to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Available variables: | |
// - Machine | |
// - interpret | |
// - assign | |
// - send | |
// - sendParent | |
// - spawn | |
// - raise | |
// - actions | |
// - XState (all XState exports) | |
const writeToDiskMachine = Machine({ | |
id: 'WriteToDiskMachine', | |
type: 'compound', | |
initial: 'writeEnqueuedWriteRequestToTmpDir', | |
states: { | |
writeEnqueuedWriteRequestToTmpDir: { | |
invoke: { | |
id: 'writeTmpFile', | |
src: (context, event) => new Promise((ohYeah) => setTimeout(ohYeah, 3 * 1000)), | |
onDone: { | |
target: 'copyTmpFileToStorageDir', | |
actions: assign((context, event) => { | |
const [ | |
// eslint-disable-next-line no-unused-vars | |
writeReqWrittenToTmpDir, | |
...restOfWriteReqs | |
] = context.temporaryWriteQueue | |
return { | |
...context, | |
temporaryWriteQueue: restOfWriteReqs, | |
} | |
}), | |
}, | |
onError: { | |
/** | |
* @todo | |
* Implement retries for: | |
* 1. Failed to write to `tmp/` directory | |
* 2. Failed to create `user${id}` directory | |
* 3. Failed to create `$ROOT_STORAGE` directory | |
*/ | |
/** | |
* @todo | |
* attempt 3 retries. If all 3 fail, enter error state | |
* and determine what that error state looks like. | |
* Maybe we should notify a global "temporaryFiles" service | |
* that can nuke all temporary storage in an attempt | |
* to free up some space. | |
*/ | |
target: 'writeEnqueuedWriteRequestToTmpDir', | |
}, | |
}, | |
}, | |
copyTmpFileToStorageDir: { | |
invoke: { | |
id: 'copyTmpFileToStorageDir', | |
src: (context, event) => new Promise((ohYeah) => setTimeout(ohYeah, 3 * 1000)), | |
onDone: { | |
target: 'success', | |
actions: 'LOG', | |
}, | |
onError: { | |
target: 'copyTmpFileToStorageDir', | |
actions: 'LOG', | |
}, | |
}, | |
}, | |
success: { | |
type: 'final', | |
}, | |
}, | |
}) | |
const readyForStorageWrites = { | |
type: 'compound', | |
initial: 'observingTemporaryWriteQueue', | |
states: { | |
observingTemporaryWriteQueue: { | |
type: 'atomic', | |
on: { | |
'': { target: 'writingToDisk', cond: 'hasEnqueuedWrite' }, | |
}, | |
}, | |
writingToDisk: { | |
invoke: { | |
id: 'WriteToDiskMachine', | |
src: writeToDiskMachine, | |
exit: 'LOG', | |
onDone: { | |
target: 'observingTemporaryWriteQueue', | |
actions: assign((context, event) => { | |
const { temporaryWriteQueue } = context | |
// eslint-disable-next-line no-unused-vars | |
const [writtenToStorage, ...restOfWriteQueue] = temporaryWriteQueue | |
return { | |
...context, | |
temporaryWriteQueue: restOfWriteQueue, | |
} | |
}), | |
}, | |
}, | |
}, | |
}, | |
} | |
let tmpWriteCounter = 0 | |
const fileSystemStorageMachine = Machine( | |
{ | |
id: 'FileSystemStorageMachine', | |
type: 'parallel', | |
context: { | |
temporaryWriteQueue: [], | |
cwd: '', | |
}, | |
states: { | |
persistingInFileSystem: { | |
initial: 'findingRootStorageDir', | |
type: 'compound', | |
states: { | |
findingRootStorageDir: { | |
type: 'atomic', | |
on: { | |
ROOT_STORAGE_DIR_EXISTS: 'findingUserStorageDir', | |
NO_ROOT_STORAGE_DIR: 'creatingRootStorageDir', | |
}, | |
}, | |
creatingRootStorageDir: { | |
type: 'atomic', | |
on: { | |
ROOT_STORAGE_DIR_EXISTS: 'findingUserStorageDir', | |
}, | |
}, | |
findingUserStorageDir: { | |
type: 'atomic', | |
on: { | |
USER_STORAGE_DIR_EXISTS: 'findingTmpDir', | |
NO_USER_STORAGE_DIR: 'creatingUserStorageDir', | |
}, | |
}, | |
creatingUserStorageDir: { | |
type: 'atomic', | |
on: { | |
USER_STORAGE_DIR_EXISTS: 'findingTmpDir', | |
}, | |
}, | |
findingTmpDir: { | |
type: 'atomic', | |
on: { | |
TMP_DIR_EXISTS: 'readyForStorageWrites', | |
NO_TMP_DIR: 'creatingTmpDir', | |
}, | |
}, | |
creatingTmpDir: { | |
type: 'atomic', | |
on: { | |
TMP_DIR_EXISTS: 'readyForStorageWrites', | |
}, | |
}, | |
readyForStorageWrites, | |
}, | |
}, | |
listeningForWriteRequests: { | |
on: { | |
ENQUEUE: { | |
target: 'listeningForWriteRequests', | |
actions: assign((context, event) => { | |
const timestamp = new Date().toISOString() | |
// const tempWriteRequest = { | |
// id: `${timestamp}$$${++tmpWriteCounter}`, | |
// key: event.key, | |
// value: event.value, | |
// timestamp: new Date().toISOString(), | |
// } | |
// return { | |
// ...context, | |
// temporaryWriteQueue: [...context.temporaryWriteQueue, tempWriteRequest], | |
// } | |
const DELETE_ME_IM_A_DEV_ONLY_VARIABLE_FOR_TESTING = { | |
id: `${timestamp}$$${++tmpWriteCounter}`, | |
key: 'jobsApi:appsync', | |
value: | |
'{"Job.asdfhkjla.location":"Walmart","Job.asdfhkjla.workOrderNumber":"2345123123","Job.asdfhkjla.customer":"Walmart Inc."}', | |
timestamp: new Date().toISOString(), | |
} | |
return { | |
...context, | |
temporaryWriteQueue: [ | |
...context.temporaryWriteQueue, | |
DELETE_ME_IM_A_DEV_ONLY_VARIABLE_FOR_TESTING, | |
], | |
} | |
}), | |
}, | |
}, | |
}, | |
}, | |
}, | |
{ | |
actions: { | |
LOG: (context, event) => { | |
console.log('LOG: ', { context, event }) | |
}, | |
}, | |
guards: { | |
hasEnqueuedWrite: (context, event) => { | |
return context.temporaryWriteQueue.length > 0 | |
}, | |
}, | |
} | |
) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment