<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
	<channel>
		<title><![CDATA[Latest posts for the topic "Problems using DMI"]]></title>
		<link>http://forums.terracotta.org/forums/posts/list/5.page</link>
		<description><![CDATA[Latest messages posted in the topic "Problems using DMI"]]></description>
		<generator>JForum - http://www.jforum.net</generator>
			<item>
				<title>Problems using DMI</title>
				<description><![CDATA[ hello guys!

I have some trouble / misunderstanding concerning DMI. What I basically try is to avoid JMS as we use Terracotta 2.6.4 anyway. So in my special case each VM runs some backend functionality but I need a way to "control" all these different instances (one per vm) from a central place without JMS/JMX. This is where I thought DMI could be of help. So regardless on which JVM you call a backend method this call should be transparently propagated to all others "backends" in the cluster.

Please see sample project.
Backendprocess (this will do all the heavy backend work. one instance per vm):
<span class="genmed"><b>Code:</b></span><br>
		<div>
		<pre bbCodeId="pre-code" style="overflow: auto; width: 95%; max-height: 350px; height:expression(this.scrollHeight > 350 ? '350px' : 'auto');">
import java.util.UUID;

public class HeavyNonPortableService
{
    final UUID _nonPortableServiceExampleOnlyField;

    public HeavyNonPortableService&#40;&#41;
    {
        _nonPortableServiceExampleOnlyField = UUID.randomUUID&#40;&#41;;
        
        System.out.println&#40;"HeavyNonPortableService created &#91;" + _nonPortableServiceExampleOnlyField + "&#93; instance=" + this&#41;;
    }

    public void serviceMethod&#40;final String s&#41;
    {
        System.out.println&#40;"serviceMethod &#91;" + s + "&#93; for &#91;" + _nonPortableServiceExampleOnlyField + "&#93; instance=" + this&#41;;
    }
}
</pre>
		</div>

a simple service wrapper to introduce DMI. This service wrapper is shared but basically should do the DMI magic in each VM and pass the message (method call) to the backend part. Parts of it are stolen from the terracotta samples:
<span class="genmed"><b>Code:</b></span><br>
		<div>
		<pre bbCodeId="pre-code" style="overflow: auto; width: 95%; max-height: 350px; height:expression(this.scrollHeight > 350 ? '350px' : 'auto');">
public class ServiceWrapper
{
    public class DMI
    {
        public void internalBroadcast&#40;final String s&#41;
        {
            _heavyNonPortableService.serviceMethod&#40;s&#41;;
        }
    }


    private final HeavyNonPortableService _heavyNonPortableService;
    private final DMI _dmi;


    public ServiceWrapper&#40;&#41;
    {
        _heavyNonPortableService = new HeavyNonPortableService&#40;&#41;;
        _dmi = new DMI&#40;&#41;;
    }

    public void broadcastMethod&#40;final String s&#41;
    {
        _dmi.internalBroadcast&#40;s&#41;;
    }
}
</pre>
		</div>

and this is the tc-config
<span class="genmed"><b>Code:</b></span><br>
		<div>
		<pre bbCodeId="pre-code" style="overflow: auto; width: 95%; max-height: 350px; height:expression(this.scrollHeight > 350 ? '350px' : 'auto');">
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;con:tc-config xmlns:con="http://www.terracotta.org/config"&gt;
    &lt;system&gt;
        &lt;configuration-model&gt;production&lt;/configuration-model&gt;
    &lt;/system&gt;
    &lt;servers&gt;
        &lt;server host="%i" name="local"&gt;
            &lt;dso-port&gt;9510&lt;/dso-port&gt;
            &lt;data&gt;terracotta&lt;/data&gt;
            &lt;logs&gt;terracotta/server-logs&lt;/logs&gt;
            &lt;statistics&gt;terracotta/cluster-statistics&lt;/statistics&gt;
        &lt;/server&gt;
    &lt;/servers&gt;
    &lt;clients&gt;
        &lt;logs&gt;/data/terracotta/logs/%&#40;node.name&#41;/&lt;/logs&gt;
        &lt;statistics&gt;/data/terracotta/client-statistics/%D/%&#40;node.name&#41;&lt;/statistics&gt;
    &lt;/clients&gt;
    &lt;application&gt;
        &lt;dso&gt;
            &lt;roots&gt;
                &lt;root&gt;
                    &lt;field-name&gt;ServiceWrapper._dmi&lt;/field-name&gt;
                    &lt;root-name&gt;Schedule_DMI&lt;/root-name&gt;
                &lt;/root&gt;
            &lt;/roots&gt;
            &lt;instrumented-classes&gt;
                &lt;include&gt;
                    &lt;class-expression&gt;ServiceWrapper$DMI&lt;/class-expression&gt;
                &lt;/include&gt;
            &lt;/instrumented-classes&gt;
            &lt;locks&gt;
                &lt;autolock auto-synchronized="true"&gt;
                    &lt;method-expression&gt;* ServiceWrapper.__INIT__&#40;..&#41;&lt;/method-expression&gt;
                    &lt;lock-level&gt;write&lt;/lock-level&gt;
                &lt;/autolock&gt;
            &lt;/locks&gt;
            &lt;distributed-methods&gt;
                &lt;method-expression&gt;void ServiceWrapper$DMI.internalBroadcast&#40;..&#41;&lt;/method-expression&gt;
            &lt;/distributed-methods&gt;
            &lt;transient-fields&gt;
                &lt;field-name&gt;ServiceWrapper._heavyNonPortableService&lt;/field-name&gt;
            &lt;/transient-fields&gt;
        &lt;/dso&gt;
    &lt;/application&gt;
&lt;/con:tc-config&gt;
</pre>
		</div>

and finally the "main" to start the service on each machine
<span class="genmed"><b>Code:</b></span><br>
		<div>
		<pre bbCodeId="pre-code" style="overflow: auto; width: 95%; max-height: 350px; height:expression(this.scrollHeight > 350 ? '350px' : 'auto');">
/**
 * -Xbootclasspath/p:/terracotta-2.6.4/lib/dso-boot/dso-boot-hotspot_osx_150_16.jar
 * -Dtc.install-root="/terracotta-2.6.4"
 * -Dtc.config=localhost:9510
 */
public class Sample_TerracottaDMI
{
    public static void main&#40;final String&#91;&#93; args&#41;
    {
        final ServiceWrapper serviceWrapper = new ServiceWrapper&#40;&#41;;
        serviceWrapper.broadcastMethod&#40;"hello"&#41;;

        try {
            Thread.currentThread&#40;&#41;.join&#40;&#41;;
            // Thread.sleep&#40;60000&#41;;    // block, whatever
        } catch &#40;final InterruptedException e&#41; {
            e.printStackTrace&#40;&#41;;
        }
    }
}
</pre>
		</div>

The following output is produced in case of two running applications
<span class="genmed"><b>Code:</b></span><br>
		<div>
		<pre bbCodeId="pre-code" style="overflow: auto; width: 95%; max-height: 350px; height:expression(this.scrollHeight > 350 ? '350px' : 'auto');">
VM1
HeavyNonPortableService created &#91;04bfb9a5-6b3b-4585-8836-95a208e7a469&#93; instance=HeavyNonPortableService@f71ad4
serviceMethod &#91;hello&#93; for &#91;04bfb9a5-6b3b-4585-8836-95a208e7a469&#93; instance=HeavyNonPortableService@f71ad4
serviceMethod &#91;hello&#93; for &#91;04bfb9a5-6b3b-4585-8836-95a208e7a469&#93; instance=HeavyNonPortableService@f71ad4
</pre>
		</div>
as you can see vm1 recognizes two calls to the service method which is correct (one call from each started vm). But VM2 is in trouble:

<span class="genmed"><b>Code:</b></span><br>
		<div>
		<pre bbCodeId="pre-code" style="overflow: auto; width: 95%; max-height: 350px; height:expression(this.scrollHeight > 350 ? '350px' : 'auto');">
HeavyNonPortableService created &#91;55bc94d1-4761-4b91-a667-ce38440118b3&#93; instance=HeavyNonPortableService@851105
Exception in thread "main" java.lang.NullPointerException
	at ServiceWrapper$DMI.__tc_dmi_internalBroadcast&#40;ServiceWrapper.java:7&#41;
	at ServiceWrapper$DMI.internalBroadcast&#40;ServiceWrapper.java&#41;
	at ServiceWrapper.broadcastMethod&#40;ServiceWrapper.java:24&#41;
	at Sample_TerracottaDMI.main&#40;Sample_TerracottaDMI.java:11&#41;
</pre>
		</div>

Thanks in advance

Jens]]></description>
				<guid isPermaLink="true">http://forums.terracotta.org/forums/posts/list/1560.page#9425</guid>
				<link>http://forums.terracotta.org/forums/posts/list/1560.page#9425</link>
				<pubDate><![CDATA[Wed, 19 Nov 2008 00:38:15]]> GMT</pubDate>
				<author><![CDATA[ titeuf1]]></author>
			</item>
			<item>
				<title>Re:Problems using DMI</title>
				<description><![CDATA[ you made the field _heavyNonPortableService transient.  So when the ServiceWrapper is materialized in the second JVM, it's null.  

Don't be fooled by the new DMI() that is called from the two ServiceWrapper instances - you are only ever getting one of these and the second assignment is thrown away.  So there is only one _dmi instance, and it's pointing to the instance that was created by the first VM.  In the second VM, when the _dmi instance is materialized, it's going to point back to the ServiceWrapper instance from the first VM, and the _heavyNonPortableService field is transient so it's going to be null since yo didn't initialize it.

More details here: http://tech.puredanger.com/2007/08/08/hello-terracotta/

Have you gone through the cookbook examples?  http://www.terracotta.org/web/display/orgsite/Tutorials
]]></description>
				<guid isPermaLink="true">http://forums.terracotta.org/forums/posts/list/1560.page#9427</guid>
				<link>http://forums.terracotta.org/forums/posts/list/1560.page#9427</link>
				<pubDate><![CDATA[Wed, 19 Nov 2008 01:18:38]]> GMT</pubDate>
				<author><![CDATA[ tgautier]]></author>
			</item>
			<item>
				<title>Re:Problems using DMI</title>
				<description><![CDATA[ I wrote some code some time ago that I think does what you are trying to do and put it in the tc-lib library - (now somewhat defunct, at least for the master worker part since that is now tim-messaging argh).

Should give you the idea:

http://svn.terracotta.org/svn/forge/projects/labs/tim-tclib/trunk/samples/strategy/readme.html
]]></description>
				<guid isPermaLink="true">http://forums.terracotta.org/forums/posts/list/1560.page#9428</guid>
				<link>http://forums.terracotta.org/forums/posts/list/1560.page#9428</link>
				<pubDate><![CDATA[Wed, 19 Nov 2008 02:00:25]]> GMT</pubDate>
				<author><![CDATA[ tgautier]]></author>
			</item>
			<item>
				<title>Re:Problems using DMI</title>
				<description><![CDATA[ Wow. Thanks for the answer in near realtime..  :D 

yes, i made it "transient" as I try to avoid the instrumentation of tons of classes required by the backend only, which only exist in the space of the VM and some of them are non portable. I am only interested in sharing the callback, not all backend classes. I can try to instrument them all, but I was looking for a solution in case of "non portable classes". All I need is a DMI callback to an instance which itself is *not* shared.
If "transient" is removed immediately the trouble starts with "instrument the HeavyNonPortableService" and add "UUID to the additional-boot-jar-classes" aso.

Any other solution here?]]></description>
				<guid isPermaLink="true">http://forums.terracotta.org/forums/posts/list/1560.page#9429</guid>
				<link>http://forums.terracotta.org/forums/posts/list/1560.page#9429</link>
				<pubDate><![CDATA[Wed, 19 Nov 2008 02:14:31]]> GMT</pubDate>
				<author><![CDATA[ titeuf1]]></author>
			</item>
			<item>
				<title>Re:Problems using DMI</title>
				<description><![CDATA[ This is in the docs Taylor referred to.

Leave it transient, don't make it final, and add this to your config:

<span class="genmed"><b>Code:</b></span><br>
		<div>
		<pre bbCodeId="pre-code" style="overflow: auto; width: 95%; max-height: 350px; height:expression(this.scrollHeight > 350 ? '350px' : 'auto');">&lt;include&gt;
  &lt;class-expression&gt;ServiceWrapper&lt;/class-expression&gt;
   &lt;on-load&gt;
     &lt;execute&gt;self._heavyNonPortableService = new HeavyNonPortableService&#40;&#41;;&lt;/execute&gt;
   &lt;/on-load&gt;
&lt;/include&gt;
</pre>
		</div>

]]></description>
				<guid isPermaLink="true">http://forums.terracotta.org/forums/posts/list/1560.page#9434</guid>
				<link>http://forums.terracotta.org/forums/posts/list/1560.page#9434</link>
				<pubDate><![CDATA[Wed, 19 Nov 2008 12:02:43]]> GMT</pubDate>
				<author><![CDATA[ gkeim]]></author>
			</item>
			<item>
				<title>Re:Problems using DMI</title>
				<description><![CDATA[ after small modifications I got it working, thanks (HeavyNonPortable is now a member of DMI, otherwise the broadcastMethod has no effect when called on the second instance).

Unfortunately there is always a but: due to the TC-Config "on-load" entry and the "redundant" new call in the DMI member initialization the HeavyNonPortable class is instantiated twice, but the first instance is thrown away. I can live with this behaviour but nevertheless this seems to be strange... 

To be honest the DMI is more difficult as expected at least from a newbie point of view :-) ]]></description>
				<guid isPermaLink="true">http://forums.terracotta.org/forums/posts/list/1560.page#9437</guid>
				<link>http://forums.terracotta.org/forums/posts/list/1560.page#9437</link>
				<pubDate><![CDATA[Wed, 19 Nov 2008 15:09:23]]> GMT</pubDate>
				<author><![CDATA[ titeuf1]]></author>
			</item>
			<item>
				<title>Re:Problems using DMI</title>
				<description><![CDATA[ Sorry, but journey still continues.  :oops:  "I forgot to mention" that the service is created by Spring using CTOR injection, so the onLoad trick is not working here. Dead end reached?  :cry:  ]]></description>
				<guid isPermaLink="true">http://forums.terracotta.org/forums/posts/list/1560.page#9441</guid>
				<link>http://forums.terracotta.org/forums/posts/list/1560.page#9441</link>
				<pubDate><![CDATA[Thu, 20 Nov 2008 06:06:14]]> GMT</pubDate>
				<author><![CDATA[ titeuf1]]></author>
			</item>
			<item>
				<title>Re:Problems using DMI</title>
				<description><![CDATA[ <p></p>

		<cite>tgautier wrote:</cite><br>
		<blockquote>I wrote some code some time ago that I think does what you are trying to do and put it in the tc-lib library - (now somewhat defunct, at least for the master worker part since that is now tim-messaging argh).

Should give you the idea:

http://svn.terracotta.org/svn/forge/projects/labs/tim-tclib/trunk/samples/strategy/readme.html
&nbsp;
		</blockquote>

I think you missed this post.  It shows how to use Queues, not DMI which will be a better solution.  ]]></description>
				<guid isPermaLink="true">http://forums.terracotta.org/forums/posts/list/1560.page#9446</guid>
				<link>http://forums.terracotta.org/forums/posts/list/1560.page#9446</link>
				<pubDate><![CDATA[Thu, 20 Nov 2008 07:26:48]]> GMT</pubDate>
				<author><![CDATA[ tgautier]]></author>
			</item>
			<item>
				<title>Re:Problems using DMI</title>
				<description><![CDATA[ I read about the master / worker pattern before, but as far I understood it this just guarantees one worker is running on one machine within the cluster to do a job. I need multiple workers doing the same job on *each* VM. 

In the meantime I believe DMI is not the right choice here. Hopefully it is allowed for a newbie to make a feature request:

Why can't you support something like a "broadcast-method" via tc-config which means: regardless in which VM the method is called it gets propagated to all others. This would be a really transparent DMI without the need to instrument tons of classes and the need for roots. And this "real" callback should allow an easy decoupling from the application and the terracotta DSO world (I guess it is just a new message to be send from TC-SERVER via the socket to the client). At the moment I have to use libs or to write tools to get the job done, which is odd because now the code depends on terracotta which terracotta DSO assumes to avoid? For sure I can not see the consequences or problems arising here, but I think that's the way how DMI should work from my point of view. Am I wrong?

And yes I switched to a LinkedBlockingQueue impl at the moment...
Again, thanks for the input and help]]></description>
				<guid isPermaLink="true">http://forums.terracotta.org/forums/posts/list/1560.page#9469</guid>
				<link>http://forums.terracotta.org/forums/posts/list/1560.page#9469</link>
				<pubDate><![CDATA[Fri, 21 Nov 2008 00:41:27]]> GMT</pubDate>
				<author><![CDATA[ titeuf1]]></author>
			</item>
	</channel>
</rss>