https://github.com/fabiosantoscode/persistent-lang
A language whose state can be persisted to disk, through the use of a fully-JSON state object
https://github.com/fabiosantoscode/persistent-lang
Last synced: 7 months ago
JSON representation
A language whose state can be persisted to disk, through the use of a fully-JSON state object
- Host: GitHub
- URL: https://github.com/fabiosantoscode/persistent-lang
- Owner: fabiosantoscode
- Created: 2021-12-30T22:54:14.000Z (about 4 years ago)
- Default Branch: main
- Last Pushed: 2022-02-10T21:56:47.000Z (almost 4 years ago)
- Last Synced: 2025-03-18T07:17:20.996Z (10 months ago)
- Language: JavaScript
- Homepage:
- Size: 287 KB
- Stars: 1
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# persistent-lang
A language that has an extreme capacity to chill out. You can save your program's state to disk or your store of choice. And you can "run" millions of concurrent processes for cheap, since you can move them to any persistent storage of your choice.
You might use this to control a process that is run by multiple machines and can last multiple days or months, without worrying about keeping a machine running for that purpose.
Here are some examples that don't currently work because this is WIP AF:
# Examples
Here's a program that controls a subscription to a paid membership
```javascript
import { createProgram } from 'persistent-lang'
import { saveStateToDisk, loadStateFromDisk } from './your-stuff.js'
import {
charge,
setSubscriptionActive,
SUBSCRIPTION_DURATION_MS,
GRACE_PERIOD_MS,
} from './your-subscription-management.js'
const machine = createProgram`
(if (== (chargeCustomer customerId) "charge-failed")
(exit "charge-failed"))
(${setSubscriptionActive} customerId true)
(while true
(wait ${SUBSCRIPTION_DURATION_MS})
(if cancelled
(exit "cancelled"))
(if (== (chargeCustomer customerId) "charge-failed")
(gracePeriod customerId)))
(fn gracePeriod [customerId]
# Give the customer a grace period, before disabling the customer's
# subscription and giving up
(set emailResult
(race
(chargeCustomer customerId)
(wait ${GRACE_PERIOD_MS} "timed-out")))
(if (== emailResult "timed-out")
(do
(${setSubscriptionActive} customerId false)
(exit "charge-failed"))))
(fn chargeCustomer []
(yield "chargeCustomer"))
`({
yieldPoints: {
async chargeCustomer(state) {
const customerId = state.processId
await charge(customerId)
},
},
async loadState(processId) {
return await loadStateFromDisk(processId)
},
async saveState(processId, newState) {
return await saveStateToDisk(processId, newState)
},
async handleExit(processId, exitArg) {
// Send a sad e-mail to the customer
},
})
export function createSubscription(customerId) {
await machine.spawnProcess({
processId: customerId,
variables: { customerId, cancelled: false },
})
}
export async function handleChargeSuccessful(customerId) {
const state = await machine.loadState(customerId)
if (state.yielded !== 'chargeCustomer') {
// We weren't expecting a charge, what's up?
throw Refund()
}
// Continue running
await state.satisfyYield()
}
export async function handleCancellation(customerId, cancelled = true) {
const state = await machine.loadState(customerId)
await state.changeGlobalVariable(state, 'cancelled', cancelled)
}
// TODO explain how waiting works, I don't know how yet but Redis will likely be involved
```