Skip to content

blockservice & exchange & bitswap: add non variadic NotifyNewBlock#242

Closed
Jorropo wants to merge 14 commits intomainfrom
notify-new-block
Closed

blockservice & exchange & bitswap: add non variadic NotifyNewBlock#242
Jorropo wants to merge 14 commits intomainfrom
notify-new-block

Conversation

@Jorropo
Copy link
Contributor

@Jorropo Jorropo commented Mar 30, 2023

Variadicts in go are just syntactic sugar around passing a slice, that means all go memory reachability rules apply, this force the compiler to heap allocate the variadic slice for virtual call, because the implementation is allowed to leak the slice (and go's interprocedural optimisations do not cover virtuals).

Passing a block without variadic will pass the itab either on the stack or decomposed through registers. Skipping having to allocate a slice.

@Jorropo Jorropo self-assigned this Mar 30, 2023
@Jorropo Jorropo requested a review from a team as a code owner March 30, 2023 16:48
@Jorropo Jorropo force-pushed the notify-new-block branch 3 times, most recently from 5344f5d to 4ff4bd2 Compare March 30, 2023 17:02
@codecov
Copy link

codecov bot commented Mar 30, 2023

Codecov Report

❌ Patch coverage is 77.55102% with 11 lines in your changes missing coverage. Please review.
✅ Project coverage is 61.60%. Comparing base (e84eae1) to head (23f130e).
⚠️ Report is 179 commits behind head on main.

Files with missing lines Patch % Lines
exchange/providing/providing.go 40.00% 4 Missing and 2 partials ⚠️
bitswap/client/client.go 86.66% 2 Missing ⚠️
blockservice/blockservice.go 50.00% 1 Missing and 1 partial ⚠️
bitswap/bitswap.go 87.50% 1 Missing ⚠️

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #242      +/-   ##
==========================================
- Coverage   61.63%   61.60%   -0.03%     
==========================================
  Files         254      254              
  Lines       31427    31469      +42     
==========================================
+ Hits        19370    19387      +17     
- Misses      10486    10507      +21     
- Partials     1571     1575       +4     
Files with missing lines Coverage Δ
...wap/client/internal/notifications/notifications.go 90.10% <100.00%> (+2.75%) ⬆️
bitswap/server/internal/decision/engine.go 92.14% <ø> (ø)
bitswap/server/server.go 58.06% <100.00%> (+0.86%) ⬆️
exchange/offline/offline.go 88.88% <100.00%> (+1.01%) ⬆️
bitswap/bitswap.go 77.47% <87.50%> (+0.77%) ⬆️
bitswap/client/client.go 78.93% <86.66%> (+0.98%) ⬆️
blockservice/blockservice.go 78.00% <50.00%> (-0.23%) ⬇️
exchange/providing/providing.go 34.61% <40.00%> (-27.89%) ⬇️

... and 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@BigLep
Copy link
Contributor

BigLep commented Mar 30, 2023

@Jorropo : I don't see an issue linked to this PR. In the absence of this, can you share more on what's motivating this PR?

@Jorropo
Copy link
Contributor Author

Jorropo commented Mar 30, 2023

@BigLep the PR and Commit bodies:

Variadicts in go are just syntactic sugar around passing a slice, that means all go memory reachability rules apply, this force the compiler to heap allocate the variadic slice for virtual call, because the implementation is allowed to leak the slice (and go's interprocedural optimisations do not cover virtuals).
Passing a block without variadic will pass the itab either on the stack or decomposed through registers. Skipping having to allocate a slice.

I can add the explanation about keeping it in-line with our other exchange APIs.


This seems like a good usecase to try the idea @guseggert is cooking (some automated code migrator), that would add the NotifyNewBlock method (which redirects to NotifyNewBlocks) automatically if you run it.

Copy link
Member

@hacdias hacdias left a comment

Choose a reason for hiding this comment

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

I don't have strong opinions on this. It seems a relatively small change that can bring memory benefits - although arguably low. If others agree, I'm fine to have it merged.

FYSA: I rebased the PR and added the updated exchange for the gateway examples.

@hacdias hacdias force-pushed the notify-new-block branch from 3af3c29 to 311cd1f Compare April 5, 2023 08:37
@BigLep
Copy link
Contributor

BigLep commented Apr 6, 2023

2023-04-06 conversation: will defer for now. Want to have clarity on how we handle breaking changes in Boxo.

@Jorropo Jorropo removed their assignment Mar 4, 2024
@gammazero gammazero added the need/maintainers-input Needs input from the current maintainer(s) label Sep 20, 2024
@gammazero
Copy link
Contributor

This is ready to merge. Let's decide if we want this or not.

Copy link
Member

@lidel lidel left a comment

Choose a reason for hiding this comment

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

Lgtm? As noted in https://github.com/ipfs/boxo/pull/242/files#r1153577309 this follows existing convention from other places (Put vs PutMany, GetBlock vs GetBlocks etc), and simplifies code slightly. If someone has custom implementation, should be trivial to migrate.

@aschmahmann any concerns?

Jorropo and others added 5 commits September 27, 2024 20:49
Variadicts in go are just syntactic sugar around passing a slice, that
means all go memory reachability rules apply, this force the compiler to
heap allocate the variadic slice for virtual call, because the
implementation is allowed to leak the slice (and go's interprocedural
optimisations do not cover virtuals).

Passing a block without variadic will pass the itab either on the stack
or decomposed through registers. Skipping having to allocate a slice.
@gammazero
Copy link
Contributor

CI fails when calling s.exchange.NotifyNewBlock(ctx, o) in blockservice.go here, but succeeds when calling s.exchange.NotifyNewBlocks(ctx, o). Ther should be no difference.

Comment on lines +386 to +387
// This is fine to do because if no calls are virtual then the compiler is able
// to see that the slice does not leak and the slice is stack allocated.
Copy link
Contributor

Choose a reason for hiding this comment

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

It is not clear whether this is true or not in the golang documentation.

Comment on lines 434 to 435
// This is actually fine to do because no calls is virtual the compiler is able
// to see that the slice does not leak and the slice is stack allocated.
Copy link
Contributor

Choose a reason for hiding this comment

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

Escape analysis results seem to contradict this:

./client.go:432:7: leaking param content: bs
./client.go:432:34: leaking param: ctx
./client.go:432:55: leaking param: blk

@gammazero
Copy link
Contributor

I do not think it is worth the extra complexity to have separate functions, one for a single block and one for multiple blocks.

@gammazero gammazero closed this Jan 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

need/maintainers-input Needs input from the current maintainer(s)

Projects

No open projects
Status: 🔎 In Review

Development

Successfully merging this pull request may close these issues.

7 participants