[Pharo-project] changes with announcements ?
Hello, Today I experimented some strange behaviours with announcements that I didn't have in some previous moose images (moose in now based on Pharo 1.3). I think that there was some changes related to announcements in pharo recently, but I could not be sure it is related. At one point in my code I have: browser on: AnnouncementClass send: #actionSelector browser announce: anAnnouncementClass. .... .... The behaviour I have is like if #actionSelector was executed asynchronously from the rest of the code below 'browser announce: ...' . Not sure but there is maybe something with exception signals. If any signal is emited in #actionSelector it will not execute the rest of the method. I was at least able to write a test that do not pass in latest pharo 1.3 Gofer new squeaksource: 'DelaunayTmpStuffs'; package: 'ExampleAnnouncementProblems'; load.
I entered an Issue: http://code.google.com/p/pharo/issues/detail?id=4296 2011/5/27 Cyrille Delaunay <cy.delaunay@gmail.com>
Hello,
Today I experimented some strange behaviours with announcements that I didn't have in some previous moose images (moose in now based on Pharo 1.3). I think that there was some changes related to announcements in pharo recently, but I could not be sure it is related.
At one point in my code I have:
browser on: AnnouncementClass send: #actionSelector browser announce: anAnnouncementClass. .... ....
The behaviour I have is like if #actionSelector was executed asynchronously from the rest of the code below 'browser announce: ...' . Not sure but there is maybe something with exception signals. If any signal is emited in #actionSelector it will not execute the rest of the method.
I was at least able to write a test that do not pass in latest pharo 1.3
Gofer new squeaksource: 'DelaunayTmpStuffs'; package: 'ExampleAnnouncementProblems'; load.
On 27 May 2011 12:05, Cyrille Delaunay <cy.delaunay@gmail.com> wrote:
Hello, Today I experimented some strange behaviours with announcements that I didn't have in some previous moose images (moose in now based on Pharo 1.3). I think that there was some changes related to announcements in pharo recently, but I could not be sure it is related. At one point in my code I have: browser on: AnnouncementClass send: #actionSelector browser announce: anAnnouncementClass. .... .... The behaviour I have is like if #actionSelector was executed asynchronously from the rest of the code below 'browser announce: ...' . Not sure but there is maybe something with exception signals. If any signal is emited in #actionSelector it will not execute the rest of the method. I was at least able to write a test that do not pass in latest pharo 1.3 Gofer new squeaksource: 'DelaunayTmpStuffs'; package: 'ExampleAnnouncementProblems'; load.
It was because on:fork: cuts the stack. If you signaling exception in your code, you should handle it before leaving your #actionSelector method. Otherwise you may put the rest recipients of announcement in danger and that's why there #on:fork: to prevent that. -- Best regards, Igor Stasenko AKA sig.
I got another issue related to that i think. In moose , at one moment in a announcement handling code, we are doing: Notification signal: 'Save successful!'. That has for consequence that the on:fork: cuts the stack and I end up with a 'MessageNotUnderstood: receiver of "sender" is nil'. So I don't know if the problem is that we are signaling a notification? if yes what should we use to notify something ? If you want to reproduce the bug, you can take this image: http://dl.dropbox.com/u/12818380/Moose-26.zip then right click on the selected model import-export / export to mse (I attached a screenshot showing that). 2011/5/27 Igor Stasenko <siguctua@gmail.com>
On 27 May 2011 12:05, Cyrille Delaunay <cy.delaunay@gmail.com> wrote:
Hello, Today I experimented some strange behaviours with announcements that I didn't have in some previous moose images (moose in now based on Pharo 1.3). I think that there was some changes related to announcements in pharo recently, but I could not be sure it is related. At one point in my code I have: browser on: AnnouncementClass send: #actionSelector browser announce: anAnnouncementClass. .... .... The behaviour I have is like if #actionSelector was executed asynchronously from the rest of the code below 'browser announce: ...' . Not sure but there is maybe something with exception signals. If any signal is emited in #actionSelector it will not execute the rest of the method. I was at least able to write a test that do not pass in latest pharo 1.3 Gofer new squeaksource: 'DelaunayTmpStuffs'; package: 'ExampleAnnouncementProblems'; load.
It was because on:fork: cuts the stack. If you signaling exception in your code, you should handle it before leaving your #actionSelector method. Otherwise you may put the rest recipients of announcement in danger and that's why there #on:fork: to prevent that.
-- Best regards, Igor Stasenko AKA sig.
On Jun 28, 2011, at 10:23 56AM, Cyrille Delaunay wrote:
I got another issue related to that i think. In moose , at one moment in a announcement handling code, we are doing: Notification signal: 'Save successful!'. That has for consequence that the on:fork: cuts the stack and I end up with a 'MessageNotUnderstood: receiver of "sender" is nil'. So I don't know if the problem is that we are signaling a notification?
Yes, if nothing inside the announcement handling code handles it, it will get handled by the announcement delivery handler which recasts it in new thread, for the reason Igor mentioned below. It's not safe to simply pass it on for handling by the code that made the announcement, if you want to ensure delivery.
if yes what should we use to notify something ?
... an Announcement?
It was because on:fork: cuts the stack. If you signaling exception in your code, you should handle it before leaving your #actionSelector method. Otherwise you may put the rest recipients of announcement in danger and that's why there #on:fork: to prevent that.
-- Best regards, Igor Stasenko AKA sig.
Cheers, Henry
Ok, thank you henrik. So I understand well that the announcement delivery handler will recast in new thread. The point I do not get (and maybe its obvious, sorry in advance), is why does it raise an error ? When I look at the debugger, it seems that at one moment in the on:fork: method we got a 'context' that is nil whereas it should not. It is quite to understand what is problem (As I do not have a lot of knowledge around that) 2011/6/28 Henrik Johansen <henrik.s.johansen@veloxit.no>
On Jun 28, 2011, at 10:23 56AM, Cyrille Delaunay wrote:
I got another issue related to that i think. In moose , at one moment in a announcement handling code, we are doing: Notification signal: 'Save successful!'. That has for consequence that the on:fork: cuts the stack and I end up with a 'MessageNotUnderstood: receiver of "sender" is nil'. So I don't know if the problem is that we are signaling a notification?
Yes, if nothing inside the announcement handling code handles it, it will get handled by the announcement delivery handler which recasts it in new thread, for the reason Igor mentioned below. It's not safe to simply pass it on for handling by the code that made the announcement, if you want to ensure delivery.
if yes what should we use to notify something ?
... an Announcement?
It was because on:fork: cuts the stack.
If you signaling exception in your code, you should handle it before leaving your #actionSelector method. Otherwise you may put the rest recipients of announcement in danger and that's why there #on:fork: to prevent that.
-- Best regards, Igor Stasenko AKA sig.
Cheers, Henry
On 28 June 2011 11:43, Cyrille Delaunay <cy.delaunay@gmail.com> wrote:
Ok, thank you henrik. So I understand well that the announcement delivery handler will recast in new thread. The point I do not get (and maybe its obvious, sorry in advance), is why does it raise an error ? When I look at the debugger, it seems that at one moment in the on:fork: method we got a 'context' that is nil whereas it should not. It is quite to understand what is problem (As I do not have a lot of knowledge around that)
What VM you using? Can you try running using other VM?
2011/6/28 Henrik Johansen <henrik.s.johansen@veloxit.no>
On Jun 28, 2011, at 10:23 56AM, Cyrille Delaunay wrote:
I got another issue related to that i think. In moose , at one moment in a announcement handling code, we are  doing: Notification signal: 'Save successful!'. That has for consequence that the on:fork: cuts the stack and I end up with a 'MessageNotUnderstood: receiver of "sender" is nil'. So I don't know if the problem is that we are signaling a notification?
Yes, if nothing inside the announcement handling code handles it, it will get handled by the announcement delivery handler which recasts it in new thread, for the reason Igor mentioned below. It's not safe to simply pass it on for handling by the code that made the announcement, if you want to ensure delivery.
if yes what should we use to notify something ?
... an Announcement?
It was because on:fork: cuts the stack. If you signaling exception in your code, you should handle it before leaving your #actionSelector method. Otherwise you may put the rest recipients of announcement in danger and that's why there #on:fork: to prevent that.
-- Best regards, Igor Stasenko AKA sig.
Cheers, Henry
-- Best regards, Igor Stasenko AKA sig.
Igor this is the code you proposed: on: exception fork: handlerAction "Activate the receiver. In case of exception, fork a new process, which will handle an error. An original process will continue running as if receiver evaluation finished and answered nil, i.e., an expression like: [ self error: 'some error'] on: Error fork: [:ex | 123 ] will always answer nil for original process, not 123. The context stack , starting from context which sent this message to receiver and up to the top of the stack will be transferred to forked process, with handlerAction on top. (so when forked process resuming, it will enter the handlerAction) " ^ self on: exception do: [:ex | | copy onDoCtx process handler bottom thisCtx | onDoCtx := thisContext. thisCtx := onDoCtx home. "find the context on stack for which this method's is sender" [ onDoCtx sender == thisCtx] whileFalse: [ onDoCtx := onDoCtx sender. onDoCtx ifNil: [ ^ ex pass ] ]. bottom := [ Processor terminateActive ] asContext. onDoCtx privSender: bottom. handler := [ handlerAction cull: ex ] asContext. handler privSender: thisContext sender. (Process forContext: handler priority: Processor activePriority) resume. "cut the stack of current process" thisContext privSender: thisCtx. nil ] 2011/6/28 Igor Stasenko <siguctua@gmail.com>
On 28 June 2011 11:43, Cyrille Delaunay <cy.delaunay@gmail.com> wrote:
Ok, thank you henrik. So I understand well that the announcement delivery handler will recast in new thread. The point I do not get (and maybe its obvious, sorry in advance), is why does it raise an error ? When I look at the debugger, it seems that at one moment in the on:fork: method we got a 'context' that is nil whereas it should not. It is quite to understand what is problem (As I do not have a lot of knowledge around that)
What VM you using? Can you try running using other VM?
2011/6/28 Henrik Johansen <henrik.s.johansen@veloxit.no>
On Jun 28, 2011, at 10:23 56AM, Cyrille Delaunay wrote:
I got another issue related to that i think. In moose , at one moment in a announcement handling code, we are doing: Notification signal: 'Save successful!'. That has for consequence that the on:fork: cuts the stack and I end up with a 'MessageNotUnderstood: receiver of "sender" is nil'. So I don't know if the problem is that we are signaling a notification?
Yes, if nothing inside the announcement handling code handles it, it
will
get handled by the announcement delivery handler which recasts it in new thread, for the reason Igor mentioned below. It's not safe to simply pass it on for handling by the code that made the announcement, if you want to ensure delivery.
if yes what should we use to notify something ?
... an Announcement?
It was because on:fork: cuts the stack. If you signaling exception in your code, you should handle it before leaving your #actionSelector method. Otherwise you may put the rest recipients of announcement in danger and that's why there #on:fork: to prevent that.
-- Best regards, Igor Stasenko AKA sig.
Cheers, Henry
-- Best regards, Igor Stasenko AKA sig.
Yes, so the problem is when exceptions are go through handler multiple times. This is not often case, but it could be happen. Apparently #on:fork: splits stack only once, and if you throw exception again it will go into exception handler, but no longer will find the sender context (since stack is cut). So the fix is to check if it can find the context, and if not , just pass an exception to handler
onDoCtx ifNil: [ ^ ex pass ] ].
should be:
onDoCtx ifNil: [ ^ handlerAction cull: ex ] ].
So, a process will be forked only once (upon first exception received), and for next ones, it will simply pass exception to handler block (since you cannot fork anymore). I will add this to issue tracker On 28 June 2011 14:22, Cyrille Delaunay <cy.delaunay@gmail.com> wrote:
Igor this is the code you proposed: on: exception fork: handlerAction "Activate the receiver. In case of exception, fork a new process, which will handle an error. An original process will continue running as if receiver evaluation finished and answered nil, i.e., an expression like: [ self error: 'some error'] on: Error fork: [:ex | Â 123 ] will always answer nil for original process, not 123. The context stack , starting from context which sent this message to receiver and up to the top of the stack will be transferred to forked process, with handlerAction on top. (so when forked process resuming, it will enter the handlerAction) " ^ self on: exception do: [:ex | | copy onDoCtx process handler bottom thisCtx | onDoCtx := thisContext. thisCtx := onDoCtx home. "find the context on stack for which this method's is sender" [ onDoCtx sender == thisCtx] whileFalse: [ onDoCtx := onDoCtx sender. onDoCtx ifNil: [ ^ ex pass ] ]. bottom := [ Processor terminateActive ] asContext. onDoCtx privSender: bottom. handler := [ handlerAction cull: ex ] asContext. handler privSender: thisContext sender. (Process forContext: handler priority: Processor activePriority) resume. "cut the stack of current process" thisContext privSender: thisCtx. nil ]
2011/6/28 Igor Stasenko <siguctua@gmail.com>
On 28 June 2011 11:43, Cyrille Delaunay <cy.delaunay@gmail.com> wrote:
Ok, thank you henrik. So I understand well that the announcement delivery handler will recast in new thread. The point I do not get (and maybe its obvious, sorry in advance), is why does it raise an error ? When I look at the debugger, it seems that at one moment in the on:fork: method we got a 'context' that is nil whereas it should not. It is quite to understand what is problem (As I do not have a lot of knowledge around that)
What VM you using? Can you try running using other VM?
2011/6/28 Henrik Johansen <henrik.s.johansen@veloxit.no>
On Jun 28, 2011, at 10:23 56AM, Cyrille Delaunay wrote:
I got another issue related to that i think. In moose , at one moment in a announcement handling code, we are  doing: Notification signal: 'Save successful!'. That has for consequence that the on:fork: cuts the stack and I end up with a 'MessageNotUnderstood: receiver of "sender" is nil'. So I don't know if the problem is that we are signaling a notification?
Yes, if nothing inside the announcement handling code handles it, it will get handled by the announcement delivery handler which recasts it in new thread, for the reason Igor mentioned below. It's not safe to simply pass it on for handling by the code that made the announcement, if you want to ensure delivery.
if yes what should we use to notify something ?
... an Announcement?
It was because on:fork: cuts the stack. If you signaling exception in your code, you should handle it before leaving your #actionSelector method. Otherwise you may put the rest recipients of announcement in danger and that's why there #on:fork: to prevent that.
-- Best regards, Igor Stasenko AKA sig.
Cheers, Henry
-- Best regards, Igor Stasenko AKA sig.
-- Best regards, Igor Stasenko AKA sig.
Thanks, Igor. It looks like Moose is a good tester for Pharo. Especially when it always runs on the latest version :). Cheers, Doru On 28 Jun 2011, at 14:40, Igor Stasenko wrote:
Yes, so the problem is when exceptions are go through handler multiple times. This is not often case, but it could be happen. Apparently #on:fork: splits stack only once, and if you throw exception again it will go into exception handler, but no longer will find the sender context (since stack is cut).
So the fix is to check if it can find the context, and if not , just pass an exception to handler
onDoCtx ifNil: [ ^ ex pass ] ].
should be:
onDoCtx ifNil: [ ^ handlerAction cull: ex ] ].
So, a process will be forked only once (upon first exception received), and for next ones, it will simply pass exception to handler block (since you cannot fork anymore).
I will add this to issue tracker
On 28 June 2011 14:22, Cyrille Delaunay <cy.delaunay@gmail.com> wrote:
Igor this is the code you proposed: on: exception fork: handlerAction "Activate the receiver. In case of exception, fork a new process, which will handle an error. An original process will continue running as if receiver evaluation finished and answered nil, i.e., an expression like: [ self error: 'some error'] on: Error fork: [:ex | 123 ] will always answer nil for original process, not 123. The context stack , starting from context which sent this message to receiver and up to the top of the stack will be transferred to forked process, with handlerAction on top. (so when forked process resuming, it will enter the handlerAction) " ^ self on: exception do: [:ex | | copy onDoCtx process handler bottom thisCtx | onDoCtx := thisContext. thisCtx := onDoCtx home. "find the context on stack for which this method's is sender" [ onDoCtx sender == thisCtx] whileFalse: [ onDoCtx := onDoCtx sender. onDoCtx ifNil: [ ^ ex pass ] ]. bottom := [ Processor terminateActive ] asContext. onDoCtx privSender: bottom. handler := [ handlerAction cull: ex ] asContext. handler privSender: thisContext sender. (Process forContext: handler priority: Processor activePriority) resume. "cut the stack of current process" thisContext privSender: thisCtx. nil ]
2011/6/28 Igor Stasenko <siguctua@gmail.com>
On 28 June 2011 11:43, Cyrille Delaunay <cy.delaunay@gmail.com> wrote:
Ok, thank you henrik. So I understand well that the announcement delivery handler will recast in new thread. The point I do not get (and maybe its obvious, sorry in advance), is why does it raise an error ? When I look at the debugger, it seems that at one moment in the on:fork: method we got a 'context' that is nil whereas it should not. It is quite to understand what is problem (As I do not have a lot of knowledge around that)
What VM you using? Can you try running using other VM?
2011/6/28 Henrik Johansen <henrik.s.johansen@veloxit.no>
On Jun 28, 2011, at 10:23 56AM, Cyrille Delaunay wrote:
I got another issue related to that i think. In moose , at one moment in a announcement handling code, we are doing: Notification signal: 'Save successful!'. That has for consequence that the on:fork: cuts the stack and I end up with a 'MessageNotUnderstood: receiver of "sender" is nil'. So I don't know if the problem is that we are signaling a notification?
Yes, if nothing inside the announcement handling code handles it, it will get handled by the announcement delivery handler which recasts it in new thread, for the reason Igor mentioned below. It's not safe to simply pass it on for handling by the code that made the announcement, if you want to ensure delivery.
if yes what should we use to notify something ?
... an Announcement?
It was because on:fork: cuts the stack. If you signaling exception in your code, you should handle it before leaving your #actionSelector method. Otherwise you may put the rest recipients of announcement in danger and that's why there #on:fork: to prevent that.
-- Best regards, Igor Stasenko AKA sig.
Cheers, Henry
-- Best regards, Igor Stasenko AKA sig.
-- Best regards, Igor Stasenko AKA sig.
-- www.tudorgirba.com "Obvious things are difficult to teach."
http://code.google.com/p/pharo/issues/detail?id=4470 Issue 4470: on:fork: re-entering multiple times fix @Marcus, is it too late to add this fix to 1.3 ? Its kind of critical one. On 28 June 2011 14:44, Tudor Girba <tudor@tudorgirba.com> wrote:
Thanks, Igor.
It looks like Moose is a good tester for Pharo. Especially when it always runs on the latest version :).
Indeed. It is always good to test stuff in real situation(s). And apparently it is much easier to hot-fix the errors, since memory is still fresh. -- Best regards, Igor Stasenko AKA sig.
On 28 Jun 2011, at 14:57, Igor Stasenko wrote:
http://code.google.com/p/pharo/issues/detail?id=4470
Issue 4470: on:fork: re-entering multiple times fix
@Marcus, is it too late to add this fix to 1.3 ? Its kind of critical one.
This would be so cool :)
On 28 June 2011 14:44, Tudor Girba <tudor@tudorgirba.com> wrote:
Thanks, Igor.
It looks like Moose is a good tester for Pharo. Especially when it always runs on the latest version :).
Indeed. It is always good to test stuff in real situation(s). And apparently it is much easier to hot-fix the errors, since memory is still fresh.
Indeed. Continuous delivery at its very best :) Cheers, Doru
-- Best regards, Igor Stasenko AKA sig.
-- www.tudorgirba.com "Don't give to get. Just give."
On Jun 28, 2011, at 2:40 10PM, Igor Stasenko wrote:
Yes, so the problem is when exceptions are go through handler multiple times. This is not often case, but it could be happen.
http://i220.photobucket.com/albums/dd143/itachi412/yo-dawg-errors.jpg ;) Cheers, Henry
participants (4)
-
Cyrille Delaunay -
Henrik Johansen -
Igor Stasenko -
Tudor Girba