# Synpse Agent
## Logic
`application` - package responsible for reading API and updating internal `store` to represent expected state
agent should be reconciling towards. It will either delete/update/create records in the `store` to set state.
`queue` - acts as a queue for workers to do one or other actions with application. It can be either Create/Delete.
`supervisor` - is supervisor for applications. It has few important reconciling functions:
`monitor`:
- Iterated via API state `store` and check what is application state in the runtime. and update ephemeral TTL `stateStore` and emits customer events.
Monitor will set states `Running`, `Failed`, `Exited`, `Unknown` - these are states on which `reconcile` will act.
As these are being refresh on every monitoring loop, it should update if state already exists. So consider scenario:
- Application is in `Failed` state.
- Monitor observed it and sets `Failed` state.
- Reconcile picks the `Failed` state and updates it to `Deleting` state to clean
- Worker picks the `Deleting` state and deletes it.
- Monitor will try to monitor again and will not find anything so will not set state store.
- TTL expires and reconcile will ack as new application is being created
`reconcile` - Will act on `store` state and `stateStore` ephemeral store. And based on it will emit either `create`, `delete` events.
- On `no stateStore` and present in `store` create
- On `Failed`, `Exited` and `Unknown` states - delete
- On `Pending` - ignore, worker is working on this
- On `Created` - ingore, worker is working on this
- On `Deleting` - ingore, worker is working on this
- On `Running when present in API` - ignore, all is ok
- On `Running when NOT in API` - delete
Very important edge case:
- As we dont have resource locking we should never allow 2 version running at the same time. So before we do start
we should check with runtime to see if it is already running (any same application container). If it is - we should not start. Maybe retry giving GC more time?
Possible scenario - Create:
- New application created - Not in API - `Pending` is set
- Worker pick it up and starts Creating. Worker keeps TTL on `Pending` so no new application will be picked up.
- It created and TTL is released.
- Monitor will pick it from Runtime and Mark as `Running`
Possible scenario - Update:
- application is in `Running` state
- `reconcile` noticed it is NOT in `store` but it is in `stateStore` (New version replaces it in store). Emits `delete` event for current one.
- `worker` deleted the application
- `reconcile` will pick new version and emit `create` event in parallel
- worker create flow has checks `IfLatest` and should prevent any creates if newer state already exits. It might create container but not start. (Need to think this one. We need check `ifLatest` and if previous version is running. Might short loop to keep iterating. If we are still latest and still have old running - wait)
- `monitor` will GC those with created but not started with `Unknown` state and so Delete event will happen.