-
Notifications
You must be signed in to change notification settings - Fork 230
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bug 1897264 - interruption support for ingestion #6246
Conversation
components/suggest/src/store.rs
Outdated
@@ -601,6 +639,8 @@ struct SuggestStoreDbs { | |||
writer: SuggestDb, | |||
/// A read-only connection used to query the database. | |||
reader: SuggestDb, | |||
/// A read-write connection used specifically for ingestion | |||
ingestion: SuggestDb, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the idea of adding a 3rd connection, but maybe we should wait on this. We could put out a quick fix for the iOS issue and tackle this separately. WDY2T?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, let's not have two read-write connections if we could, please...having multiple writers is a bag of hurt in SQLite. We unfortunately learned that the hard way with Rust Places, where we saw contention between the writer and syncer—and when we tried that on Desktop, we could even wedge one writer permanently, so that it always returned SQLITE_BUSY
😱
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems good for now, I updated the PR to do that.
Long-term, I still kind of like separating the connections since it allows you to cancel each separately. The current interrupt_ingestion
method could also interrupt a call to dismiss_suggestion
. I think there's a way to do it safely, although maybe it's just because I haven't been burned by SQLite yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, @bendk, and I'm truly sorry if my reaction came off as short in any way—I was running a little late for an appointment earlier, and you deserved a more thoughtful response with more time. I left some more noodlings on https://bugzilla.mozilla.org/show_bug.cgi?id=1897299 for your consideration 🧠
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #6246 +/- ##
===========================================
- Coverage 83.68% 50.85% -32.84%
===========================================
Files 117 112 -5
Lines 15653 11811 -3842
===========================================
- Hits 13099 6006 -7093
- Misses 2554 5805 +3251 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The shape of the API looks great (thanks for doing this!), but having a second writer is inviting dragons 🐉
Would you mind dropping that in favor of having interrupt_ingestion()
just interrupt the existing writer
?
401dd7f
to
319bc7f
Compare
components/suggest/src/db.rs
Outdated
@@ -651,10 +659,11 @@ impl<'a> SuggestDao<'a> { | |||
&mut self, | |||
record_id: &SuggestRecordId, | |||
suggestions: &[DownloadedAmoSuggestion], | |||
ingest_interrupt_scope: &SqlInterruptScope, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh, I had SuggestDao
hold an interrupt scope specifically so that we could avoid passing it around 😄
The Dao
is a transient object that only lives for the lifetime of a read()
or write()
call, so I was thinking that, if you wanted a separate interrupt scope for just ingestion, you could create a SuggestDao
with a separate interrupt scope, and that SuggestDao
would only live for the lifetime of the ingestion.
WDYT? This isn't blocking by any means; I just wanted to make sure I understood if there were other reasons for passing the scope around explicitly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The transaction gets committed at end of write
and I didn't want to change that behavior. But it does seem better to just pass around the SuggestDao
. I'll update the PR to create a single DAO for the entire ingestion and add a SuggestDao::commit
method that we can call. This seems better all-around, I prefer seeing explicit commits in the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a comment about passing the interrupt scope around explicitly now, but no need to block on that. Thanks again, @bendk!
319bc7f
to
863f41d
Compare
Updated the change so that instead of creating a new scope at the top of I'm thinking we can merge this, which will unblock Lina to fix things on iOS, then create a follow-up PR that adds back some extra commits. I also think we could further simplify some code now that we only have one |
a1ab648
to
2358b87
Compare
Pushing one more change that adds back the transaction support here. I did this because a) I realized it wasn't that hard to add it back and b) the code is not quite ready for the other cleanups I wanted to do. Also, I renamed the method back to Sorry for moving the target with this one, but I think it's ready for review again now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still LGTM, thanks!
/// if [Self::interrupt_handle::interrupt] is called after the operation starts. Calling | ||
/// [Self::write] multiple times during the operation risks missing a call that happens after | ||
/// between those calls. | ||
pub fn write_scope(&self) -> Result<WriteScope> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oooo, I really like this!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, could you also update the README.md to reflect the change? It only covers how to use interrupt()
for query()
.
I was gonna ask if it makes sense to consolidate those interrupt calls as consumers almost certainly need to come here to check the document to tell which one should be used. Would |
2358b87
to
50a6710
Compare
I like this idea, but I feel like "scope" is already somewhat overloaded so I called it |
50a6710
to
e358269
Compare
components/suggest/src/suggest.udl
Outdated
enum InterruptKind { | ||
"Read", | ||
"Write", | ||
"Everything", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Absolute nitpick: What do you think of ReadWrite
instead of Everything
as a name? 😅
This new API is so elegant!
Added an `interrupt_everything` method that interrupts both the read and write connection. This is intended for iOS to use to interrupt the suggest component during shutdown. See https://bugzilla.mozilla.org/show_bug.cgi?id=1897299 for a discussion on next steps here. Created a new `WriteScope` type that stores an interrupt scope that can be used for multiple `write` calls. This allows the ingestion code to catch all interruptions that happened after the ingestion started. With the old system, if `interrupt_everything` was called in-between ingestion two types then we might miss it.
e358269
to
767350e
Compare
@Mergifyio backport release-v127 |
✅ Backports have been created
|
Bug 1897264 - interruption support for ingestion (backport #6246)
Added an
interrupt_everything
method that interrupts both the read and write connection. This is intended for iOS to use to interrupt the suggest component during shutdown. See https://bugzilla.mozilla.org/show_bug.cgi?id=1897299 for a discussion on next steps here.Created a new
WriteScope
type that stores an interrupt scope that can be used for multiplewrite
calls. This allows the ingestion code to catch all interruptions that happened after the ingestion started. With the old system, ifinterrupt_everything
was called in-between ingestion two types then we might miss it.Pull Request checklist
[ci full]
to the PR title.Branch builds: add
[firefox-android: branch-name]
to the PR title.