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

Kernel#Sync: pass annotation: keyword to newly created Reactor #348

Merged
merged 7 commits into from
Oct 29, 2024

Conversation

paddor
Copy link
Contributor

@paddor paddor commented Oct 1, 2024

Just for symmetry with Kernel#Async. In a library I changed the specs to always run in a Sync {...} block which meant I had to change the main reactor from Async(annotation: 'x') { ... } to Async(annotation: 'x') { ... }.wait because Kernel#Sync didn't take an annotation. This PR allows it to be just Sync(annotation: 'x') { ... }.

@ioquatix
Copy link
Member

How do you think we should handle the following case?

Async(annotation: "foo") do
  Sync(annotation: "bar") do |task|
    puts task.annotation
  end
end

@paddor
Copy link
Contributor Author

paddor commented Oct 29, 2024

Could Kernel#Sync replace the annotation of the current task and then restore it to the previous value?

@ioquatix
Copy link
Member

ioquatix commented Oct 29, 2024

Could Kernel#Sync replace the annotation of the current task and then restore it to the previous value?

Yeah, I considered that too. I think it's a reasonable idea. I think we can take advantage of https://github.com/ioquatix/fiber-annotation/blob/main/lib/fiber/annotation.rb#L31-L45

@paddor
Copy link
Contributor Author

paddor commented Oct 29, 2024

Task#annotate / Fiber#annotate would be nice but they don't yield the task to the block.

@paddor
Copy link
Contributor Author

paddor commented Oct 29, 2024

Ah wait, that's not a big deal. I'm working on it...

@ioquatix
Copy link
Member

We can always update the fiber annotation gem to support ... arguments to yield or something like that.

lib/kernel/sync.rb Outdated Show resolved Hide resolved
@paddor
Copy link
Contributor Author

paddor commented Oct 29, 2024

I think this is ready.

lib/kernel/sync.rb Outdated Show resolved Hide resolved
lib/kernel/sync.rb Outdated Show resolved Hide resolved
@ioquatix ioquatix merged commit 9b94ec1 into socketry:main Oct 29, 2024
26 of 28 checks passed
@ioquatix
Copy link
Member

Thanks for your contribution.

I understand the value of this change, and think that it's ultimately a good change.

However, I want to point out there will be a slight performance hit. Hopefully things like YJIT mitigate it on the fast path (no annotation, existing task).

I also had some thoughts around how to present annotations in backtrace, e.g. an annotation is stack frame specific and gets added to exception messages, etc. In other words, there is more work to be done in this area FYI.

@ioquatix ioquatix self-assigned this Oct 29, 2024
@ioquatix ioquatix added this to the v2.18.0 milestone Oct 29, 2024
@paddor
Copy link
Contributor Author

paddor commented Oct 30, 2024

Thanks for the guidance and merging.

I'd be a little surprised if the performance hit was even measurable.

Annotations in the backtrace sounds like a good idea. Let me know if I can help in any way.

@ioquatix
Copy link
Member

ioquatix commented Oct 30, 2024

Annotating the call stack would be an alternative to annotating the fiber. However, for the purpose of Async, I think it wouldn't look that different.

We'd need to write up a proposal on <bugs.ruby-lang.org> and propose a similar but non-finer specific interface for "annotate the current stack frame". If it was accepted, then Sync(annotation:) would simply use that (and we'd also need an interface for getting the top most annotation).

@ioquatix
Copy link
Member

https://bugs.ruby-lang.org/issues/19056 was the previous discussion, and at the meeting we discussed having per-call-stack annotations (could be added to exception backtrace too).

@paddor
Copy link
Contributor Author

paddor commented Oct 30, 2024

So something like Callstack.annotate(my_annotation) { ... }? And I guess (because Matz said it would have to be stacked) it would have to append the annotation into an array (like breadcrumbs), so Callstack.annotations would return the entire Array (like Class#ancestors), and pop from that array when the annotated block is done.

What did you mean by "APM" in that discussion on bugs.ruby-lang.org? If it's advanced power management, I don't know how that relates to this.

@ioquatix
Copy link
Member

Application performance monitoring (APM) is the practice of tracking key software application performance metrics using monitoring software and telemetry data. Practitioners use APM to ensure system availability, optimize service performance and response times, and improve user experiences.

@paddor
Copy link
Contributor Author

paddor commented Oct 30, 2024

Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants