Skip to content

Improvement: better concurrency support of interleaved futures #64

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

Merged
merged 20 commits into from
Sep 21, 2023

Conversation

ten3roberts
Copy link
Contributor

See: #60

src/lib.rs Outdated
let bufs = &mut *self.bufs.lock().unwrap();

// Store the most recently entered span
let _ = self.current_span.compare_exchange(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am not entirely sure what the new value should be here.

Closing a span won't necessarily mean that the parent span is the new active one, as any span could be printed next on a different thread. I think for non-concurrent usage the parent of a span will most often be the currently active span, or it will be closed immediately afterwards (SeqCst).

What are you thoughts @davidbarsky?

Copy link
Owner

@davidbarsky davidbarsky Aug 9, 2023

Choose a reason for hiding this comment

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

Sorry, I had missed this mention. I'm not sure why the notification didn't go through as it normally does—I blame my impulse self for running an iOS beta.

I think for non-concurrent usage the parent of a span will most often be the currently active span, or it will be closed immediately afterwards (SeqCst).

That's correct, yes. Spans are open so long their child spans are open, which necessitates closing spans from child to parent.

}

/// Runs `A` and `B` side by side and only yields items present in `B`
struct DifferenceIter<L, R, F> {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is used for only printing the relevant new spans.

Solving the Lowest Common Ancestor problem for the span tree

@ten3roberts
Copy link
Contributor Author

image

Added a debugging for span modes, to see why a branch was printed, to be able to debug if it is a retrace, pre-open or open event

@ten3roberts
Copy link
Contributor Author

When working on this I've managed to implement two other things using the same bit of code that was required for retracing two work.

The changes include:

Additionally, there is a small with_span_modes that prints the kind of the span event such as open/pre_open/close etc, which aids when debugging this crate and figuring out what a line. If you don't want it to remain I'll happily remove it

I've added examples and tests for each.

Here is how retracing looks:

image

Please do let me know what you think of this @oli-obk

@ten3roberts ten3roberts marked this pull request as ready for review August 9, 2023 15:50
@davidbarsky
Copy link
Owner

I really like the overall outcome of this in the screenshot! I'll need to dig into the specifics, though.

@ten3roberts
Copy link
Contributor Author

ten3roberts commented Aug 9, 2023

Good to hear.

Interestingly the deferred/lazy spans didn't require any extensive rewrite, but rather didn't need more than simply doing nothing in on_new_span and having the existing span retracing print the span when encountered in an event.

Another thing that changed is having the Buffers locked and passed to write_span_info rather than locking inside of it (inside the retrace loop etc), to avoid interleaving multithreaded calls as that would muddle the current_span temporal context.

The default behavior is unchanged, and the retracing is opt-in. I am consider if it may be a good idea for discoverability and autoimprovement if retracing could be enabled by default, as having it off just makes events seem to appear in the wrong span. The retracing feature essential connects each "timeline" or branch of events with a line branching off the right vertical line, which can be seen in the screenshot above when interleaving spans of different depths and parents.

@ten3roberts
Copy link
Contributor Author

ten3roberts commented Aug 12, 2023

Another thing that I've been wondering about is the standard or suggested style for writing tracing events.

It seems as if both you and hyperium use the lowercase terse/machine like format, while some others use a more sentence or subject-verb-object style f writing them

For example

trace!("ignore unknown frame type {:#x}", ty);

While others have used

trace!("Ignoring unknown frame type {:#x}", ty)

I've awkardly found both in this PR 😅, just wanting to keep consistency of this while I am at it.

Anyways, hoping you find this PR useful and in good quality. Let me know if you have any changes you request and I'll be happy to fix them up

@davidbarsky
Copy link
Owner

The default behavior is unchanged, and the retracing is opt-in. I am consider if it may be a good idea for discoverability and autoimprovement if retracing could be enabled by default, as having it off just makes events seem to appear in the wrong span. The retracing feature essential connects each "timeline" or branch of events with a line branching off the right vertical line, which can be seen in the screenshot above when interleaving spans of different depths and parents.

I think for those that need it, they really need. We can always call it out on the main documentation page.

It seems as if both you and hyperium use the lowercase terse/machine like format, while some others use a more sentence or subject-verb-object style f writing them

Yeah, my feeling is the value—pardon the pun—are the key/values on spans and events. The sentence is really more to provide a hint of context on what is happening, so a full sentence isn't as valuable.

I've awkardly found both in this PR 😅, just wanting to keep consistency of this while I am at it.

I think this occurred because the original example was lifted from slog, which preferred more of the sentence-style to logging.

@ten3roberts
Copy link
Contributor Author

Alright thanks, that really explains it.

I'll fix those sentences up to be consistent, and I suppose the current doc comments on the builder are enough, as there doesn't seem to be any "overview" in lib.rs to consider.

May I re-add you as a reviewer when done with that? Is there anything more I should add or fix up?

@ten3roberts
Copy link
Contributor Author

Hi @oli-obk do you think we could get this PR reviewed?

I'd love to hear what you think about this feature and its implementation

@oli-obk
Copy link
Collaborator

oli-obk commented Sep 4, 2023

Sorry I'm still completely swamped with rustc reviews since I returned from vacation last week. The rendered version lgtm, but I won't get to reviewing the code in depth in the next week

@ten3roberts
Copy link
Contributor Author

Sorry I'm still completely swamped with rustc reviews since I returned from vacation last week. The rendered version lgtm, but I won't get to reviewing the code in depth in the next week

No worries at all, this is the nature of asynchronous work, so don't stress yourself over it. Just wanted to know all was ok and that this wasn't forgotten 😊

Do you think a new crates.io version could be published with this, or are there more things that are in planning before that?

@oli-obk
Copy link
Collaborator

oli-obk commented Sep 21, 2023

I'm looking at #68, too, so we could publish with both changes. If it looks like it needs more time, we'll publish a new version with just everything up to this PR

@oli-obk oli-obk merged commit 8aa51bc into davidbarsky:main Sep 21, 2023
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.

3 participants