Jochen Theodorou | 17 Jul 15:44
Gravatar

Re: [groovy-user] creating a new method inside invokeMethod

Rubee schrieb:
> I've seen examples where invokeMethod creates a new method so that, on the
> next call, the performance hit is reduced. Here's an example from Venkat
> Subramaniam's excellent "Programming Groovy." (See p. 223.)
> 
> class Manager
> {
> .......
> def methodMissing(String name, args)
>   {
>     println "intercepting call to $name..."
>     def delegateTo = null
>     
>     if(name.startsWith('simple')) { delegateTo = worker }
>     if(name.startsWith('advanced')) { delegateTo = expert }
>     
>     if (delegateTo?.metaClass.respondsTo(delegateTo, name, args)) 
>     { 
>       Manager.metaClass."${name}" = { Object[] varArgs -> 
>             return delegateTo.invokeMethod(name, *varArgs)
>       }
> 
>       return delegateTo.invokeMethod(name, args)
>     }
>     
>     throw new MissingMethodException(name, Manager.class, args)
>   }
> ........
> } //end class
> 
> I need to do this is an webapp, which means my analog to the Manager class
> shown here lives in a multi-threaded enviroment.  
> 
> My question, then, is how do I handle method-creation in a mulit-threaded
> environment?  I suppose that question boils down to: what do I need to
> synchronize on, if anything?  

You should not need to synchronize on something when you want to add the 
method. Adding and asking for the method should be threadsafe... but 
there is a gap between those two actions, so there is the chance that 
someone will add the method after you asked. Isn't there << which throws 
an exception when the method already exists? I think that would solve 
the problem for you.. thinking further I guess the respondsTo isn't 
neded at all, because method missing wouldn't have been called is the 
method is there. I mean there is no point in adding the method when 
missing method gets called later anyway.

> I hope developers are doing this kind of thing all the time, and maybe
> someone can show me a real-world example.

So my idea would be:

>> class Manager
>> {
>> .......
>> def methodMissing(String name, args)
>>   {
>>     println "intercepting call to $name..."
>>     def delegateTo = null
>>     
>>     if(name.startsWith('simple')) { delegateTo = worker }
>>     if(name.startsWith('advanced')) { delegateTo = expert }
>>     
>>       Manager.metaClass."${name}" << { Object[] varArgs -> 
>>             return delegateTo.invokeMethod(name, *varArgs)
>>       }
>>       return delegateTo.invokeMethod(name, args)
>>     
>>     throw new MissingMethodException(name, Manager.class, args)
>>   }
>> ........
>> } //end class

I forgot what exception will be thrown when << tries to overwrite an 
existing method, but that should be easy to find out.

bye blackdrag

--

-- 
Jochen "blackdrag" Theodorou
The Groovy Project Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/
http://www.g2one.com/

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Gmane