From: Caleb Clausen Date: 2010-05-31T05:03:32+09:00 Subject: Re: Interrupting the evaluation of a ruby script On 5/29/10, Emmanuel Emmanuel wrote: > > Thanks very much for your answer. > >> my_string = "some stuff here to evaluate" >> ... figure out where to insert a yield statement into my_string >> my_string.instance_eval do >> some_condition == true ? (throw error) : (carry on) >> end > This would not work since the string I am evaluating could be anyything > (even 2000 line length), it is an input given by the user basically... > so no way I can parse it to understand where to insert the yield > statement ! > >> Ruby noob here. I think what technique you would have to use would be >> determined by your requirements for stopping evaluation. If you need to >> "freeze" the eval, check some value, then carry on (or not), you can >> accomplish it within the same thread. If you need to have something like >> say, an independent timer which could send an interrupt to the eval, >> then you would need multi threading. If single threading is acceptable, >> couldn't you do something like the following? (forgive me for the >> horrible pseudocode) > > I guess you are right I should use multithreading... I am going to try > that ..... > If I terminate the (sub)thread suddenly (from the main thread), is there > a way to catch this termination in the subthread so that I could do some > cleaning first ? > > It is VERY important for me that the evaluation is very fast... I am > afraid that put it in a separate thread, and having the main thread just > being in charged of eventually stopping this subthread (so waking up > every second) is going to slow down the evaluation quite a lot. > > I understood, ruby's threading system is not really optiomized ? Am I > wrong ? > > What would be best way to have the main thread waking up every second > (to see if teh user asks for interruption) taking as little of CPU as > possible ? If this is what you want to do, you should probably use the Timeout module in timeout.rb, which does this already (spawn another thread to limit time taken by some block of code). OTOH, you must consider whether you can trust the code that your users are giving you. It would be very easy for user code to simply kill the timeout thread, (whether or not you use the timeout library) and thus bypass your timeout. If you put user code in a separate process, it would be somewhat harder for them to bypass the timeout, but I think still possible. The issue of executing code that you can't trust is a hairy one, and not well solved for ruby.