feat(service): Instrument the remaining backends with the change stream - #607
feat(service): Instrument the remaining backends with the change stream#607matt-codecov wants to merge 2 commits into
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #607 +/- ##
==========================================
+ Coverage 88.54% 88.64% +0.09%
==========================================
Files 105 105
Lines 17289 17449 +160
==========================================
+ Hits 15308 15467 +159
- Misses 1981 1982 +1
☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
| New `ChangeStream` implementations may follow the same pattern: | ||
| - per-backend configuration for per-backend IDs or configuration | ||
| - service-wide configuration for a stream sink | ||
| - glue code in and around `ChangeStreamFactory` |
There was a problem hiding this comment.
Not sure what you meant by this
There was a problem hiding this comment.
If you want to add a new ChangeStream implementor to certain backends, you need to change:
- The Service config to configure where the changes get written for that particular change stream (for COGS this is the
storage_cogstop-level config key in the yaml -- you do this at the Service level so you can share a single Kafka producer/db connection/etc.) - The backend config for the backends that should support such change stream implementation (in this PR we needed to add the
cogsfield toFileSystemConfig) ChangeStreamFactory::newand::build, to teach the factory how to use those new configs.
| /// Creates a new [`LocalFsBackend`] rooted at the directory in `config`. | ||
| pub fn new(config: FileSystemConfig) -> Self { | ||
| Self { path: config.path } | ||
| pub fn new(config: FileSystemConfig, streams: &ChangeStreamFactory) -> Self { |
There was a problem hiding this comment.
Why are we using &ChangeStreamFactory here instead of Arc<dyn ChangeStream>? Shouldn't ChangeStream implementation is dynamically switchable, in SaaS we can use the cost tracker, in self-hosted we can use the garbage collector?
There was a problem hiding this comment.
I was also thinking about this. See https://github.com/getsentry/objectstore/pull/607/changes#r3952214185 for my though process. Matt will probably have more to add to this as well.
| /// - `OS__STORAGE__COGS__SHARED_RESOURCE_ID=s3_objectstore` | ||
| /// - `OS__STORAGE__COGS__SAMPLE_RATE=1.0` (optional) | ||
| #[serde(default, skip_serializing_if = "Option::is_none")] | ||
| pub cogs: Option<CostTrackerStreamConfig>, |
There was a problem hiding this comment.
I understand the design with the ChangeStreamFactory now.
That allows us to define a pub cleanup: Option<CleanupStreamConfig> for expiry cleanup just here but not on e.g. the GCS backend, making it impossible to construct a GCS backend with a CleanupChangeStream.
If we were passing in Arc<dyn ChangeStream> to each backend instead, we wouldn't be able to enforce that as easily.
| `size` is a count of bytes that the backend actually stores for an object. This | ||
| includes object payloads, metadata, and sometimes backend-specific overhead. |
There was a problem hiding this comment.
Nit: should we say that size should be an estimate or proportional to the bytes that you're storing/billed for in/by the backend, rather than literally the size?
Why: looking at S3 docs it seems that the storage bytes you're charged for has some nuances that depend on things such as the storage tier: https://aws.amazon.com/s3/pricing/#:~:text=*%20S3%20Intelligent%2DTiering,pricing%20page.
ChangeStreamabstraction inobjectstore-service/docs/architecture.mdLocalFsBackend,InMemoryBackend, andS3CompatibleBackendwith aChangeStreamFactory/self.change_streamhandleself.change_streamCloses FS-489
also includes a drive-by fix: previously the S3 backend would return
Err(...)when deleting a non-existent object. the rest of our backends returnOk(())in that case. so this PR makes the S3 backend match the other backends' behavior