Skip to content
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

fix(blockexchange): ensures futures are asyncSpawned #1037

Merged
merged 3 commits into from
Dec 16, 2024

Conversation

emizzle
Copy link
Contributor

@emizzle emizzle commented Dec 13, 2024

  • asyncSpawn futures (that raise []) in advertiser, discovery, and engine modules
  • prevents failures in the futures from silently failing
  • replaces engine.blockexcTasks with TrackedFutures, which tracks and cancels long-running futures

@emizzle emizzle force-pushed the fix/fix-async-futures/2-blockexchange branch 4 times, most recently from c3e5397 to 00b09b2 Compare December 13, 2024 03:20
@emizzle emizzle changed the title feat(blockexchange): ensures futures are asyncSpawned fix(blockexchange): ensures futures are asyncSpawned Dec 13, 2024
@@ -129,9 +137,11 @@ proc start*(b: Advertiser) {.async.} =

b.advertiserRunning = true
for i in 0..<b.concurrentAdvReqs:
b.advertiseTasks.add(processQueueLoop(b))
let fut = b.processQueueLoop().track(b)
asyncSpawn fut
Copy link
Contributor

@benbierens benbierens Dec 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see how track() works, but I don't recommend this. If I look for the usage of the "trackedFutures" field in the engine.nim, all I find is the creation and cancel-call. I'd much prefer the connection between the field and track() to be explicit at the point of use. So a small change like
let fut = b.processQueueLoop().track(b.trackedFutures)

What do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I confess I'm always weirded out when I see this. My simple brain parses that the Future returned by processQueuedLoop is tracking something, when in fact there's this unexpected inversion and it's actually b.trackedFutures that is tracking b.processQueueLoop.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, the API could use some work, but that can be handled in another PR and applied across the codebase.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are reasons the API ended up where we are now, but those reasons are being removed from the codebase, so we'll have some freedom to change the API (not in this PR).

Something like this would be better?

let fut = b.processQueueLoop()
b.trackedFutures.track(fut)
asyncSpawn fut

Copy link
Contributor

@marcinczenko marcinczenko Dec 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking just at the code:

let fut = b.processQueueLoop().track(b)

it is not evident what it does. To understand you have to check the return type of processQueueLoop which apparently has ability to “track” objects of the type corresponding to b. The reader really needs to dissect the code to understand.

The proposed alternative is way easier to understand. You could even just say b.trackedFutures.add(fut) or maybe even instead of trackedFutures something like a type FutureTracker and then b.futureTracker.add(fut) or maybe there could be a special type of a “TrackedFuture” which would take care of itself magically (I do not know if that would work here - I did not dive into details)…

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe there could be a special type of a “TrackedFuture” which would take care of itself magically

There are definitely ways to do this, however I'm not a fan of magic things in most cases because they tend to hide what's happening and make things harder to reason, harder to debug, and harder to add new features (even though it's usually intended to make things easier to implement, however it's rarely the case).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When saying "magic" I mean more something in the style of RAII (Resource Acquisition is Initialization) common in C++ and less in the style of Java/C#/Spring like fancy annotations.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR here: #1046


await sleepAsync(b.advertiseLocalStoreLoopSleep)
except CancelledError:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Btw, we should probably plan to drop the v3 compat mode from Chronos as it'll then start warning about those all over.

Copy link
Member

@gmega gmega left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice improvement, and good idea to reuse the TrackedFutures abstraction that we already have in place of seq[Future].

@emizzle emizzle force-pushed the fix/fix-async-futures/2-blockexchange branch from 00b09b2 to 6b9f917 Compare December 16, 2024 04:10
@emizzle emizzle enabled auto-merge December 16, 2024 04:10
@emizzle emizzle added this pull request to the merge queue Dec 16, 2024
Merged via the queue into master with commit b0cc27f Dec 16, 2024
17 checks passed
@emizzle emizzle deleted the fix/fix-async-futures/2-blockexchange branch December 16, 2024 07:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants