This improves the overall responsiveness of the system substantially, but does make each iteration *slightly* slower, distributing the up-front cost across the batch.
Two main changes:
1. Create BatchSessions immediately, but do not create a whole graph execution state until the batch is executed.
BatchSessions are created with a `session_id` that does not exist in sessions database.
The default state is changed to `"uninitialized"` to better represent this.
Results: Time to create 5000 batches reduced from over 30s to 2.5s
2. Use `executemany()` to retrieve lists of created sessions.
Results: time to create 5000 batches reduced from 2.5s to under 0.5s
Other changes:
- set BatchSession state to `"in_progress"` just before `invoke()` is called
- rename a few methods to accomodate the new behaviour
- remove unused `BatchProcessStorage.get_created_sessions()` method
The internal `BatchProcessStorage.get_session()` method throws when it finds nothing, but we were not catching any exceptions.
This caused a exception when the batch manager handles a `graph_execution_state_complete` event that did not originate from a batch.
Fixed by handling the exception.
If the values from the `session_dict` are invalid, the model instantiation will fail, or if we end up with an invalid `batch_id`, the app will not run. So I think just parsing the dict directly is equivalent.
Also the LSP analyser is pleased now - no red squigglies.
Providing a `default_factory` is enough for pydantic to know to create the attribute on instantiation if it's not already provided. We can then make make the typing just `str`.
- also implement pessimistic updates for starring, only changing the images that were successfully updated by backend
- some autoformat changes crept in