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

Limitation of settrace of the first target.switch() #129

Open
zhangyangyu opened this issue Mar 13, 2018 · 4 comments
Open

Limitation of settrace of the first target.switch() #129

zhangyangyu opened this issue Mar 13, 2018 · 4 comments

Comments

@zhangyangyu
Copy link

zhangyangyu commented Mar 13, 2018

I am using settrace and I encounters a limitation of it. The problem is we could only get limited info with the target of its first switch call. settrace is called between the greenlet starts and run is executed. This means I have no way to get any info about what this greenlet is going to do or is doing. No stack of run, not available run attribute. So in an extreme case, if it blocks in the first switch call, settrace could not give me necessary info.

@snaury
Copy link
Contributor

snaury commented Mar 13, 2018

I'm not sure what you're expecting there to be. There's no stack, because the new target has never been executed yet, and it's stack is literally empty. There's no run, because when greenlet is executed for the first time it's run attribute disappears, it's part of the protocol, and even if it didn't I'm not sure how would that help you exactly? When your trace function is called, you already know that current greenlet will start executing upon return.

If you want to trace python code you may try using sys.settrace or sys.setprofile.

@zhangyangyu
Copy link
Author

zhangyangyu commented Mar 14, 2018

When your trace function is called, you already know that current greenlet will start executing upon return.

That's the problem, I know the target greenlet will start executing but I can't know what it is going to execute. If I understand correctly, at this time, greenlet.gr_frame and sys._getframe() should all be None. Then how could I know where this greenlet.switch is called in the source code?

I am using settrace to trace greenlet switches. I need a way to identify each greenlet, identity alone is not enough since it doesn't help determine where the greenlet is executed in the source code. For most cases, backtraces, no matter they come from greenlet.gr_frame and sys._getframe(), help. When there is no backtraces, and there is no run, I don't get a proper way to identify it.

Honestly speaking if there is also create and delete events they could help, for functionality, for programming. But I know you have said you don't want to trace greenlet lifecycles long ago in a previous issue.

@snaury
Copy link
Contributor

snaury commented Mar 14, 2018

The purpose of greenlet tracing is to identify which greenlet stopped executing and which greenlet is starting to execute, and initially the idea was to help profilers that e.g. use sys.setprofile for per-greenlet program tracking.

Again I'm not sure what you're trying to do. If you want to build something like greenlet -> execution_time dict, you can already do that with greenlet.settrace (and you shouldn't need to track frames, as description of what each greenlet represents should be elsewhere, e.g. in subclasses like gevent.Greenlet). If you want a high-level knowledge of what your program is doing at any time you need to use sys.setprofile anyway, and it is actually possible to catch greenlet.switch before it executes for the first time with (frame, 'c_call', greenlet.switch) event.

@zhangyangyu
Copy link
Author

zhangyangyu commented Mar 14, 2018

If you want to build something like greenlet -> execution_time dict

Almost what I am doing. Why I want more info and track frames is because when I find there is some greenlet in the dict occupies too long time, I want to quickly identify where actually it is in the source code. Simply having the object itself and execution time won't take me to the final place.

description of what each greenlet represents should be elsewhere, e.g. in subclasses like gevent.Greenlet

In my case not able to expect what libraries users are using. :-(

and it is actually possible to catch greenlet.switch before it executes for the first time with (frame, 'c_call', greenlet.switch) event.

Yes, setprofile is a solution here. I could expect a (frame, 'c_call', greenlet.switch) event comes before a greenlet.settrace event. But since all I care about is greenlet I don't really want to pull setprofile in. It makes the performance worse (Yes, I care about it :-( ).

Thanks to your reply first. I just think it would be nice if I could get the information just using settrace, for the first switch call. But honestly speaking I don't find an elegant way to make this happen for myself.

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

No branches or pull requests

2 participants