Singleton and -instance option

860 views
Skip to first unread message

uppsax

unread,
Jul 29, 2013, 9:46:57 AM7/29/13
to ve...@googlegroups.com
Hi

Under the situaion:

* Starting point of application is a worker verticle 
* There is a singleton class that contains global variables
* The worker verticle calls other class methods and they get/set the singleton

I am assuming that this will work and keeps Singleton's consistency.

My question is if the following statement is true or false.

"When using '-instances 5' option, all 5 Singletons will not affect each other and each Singleton keeps its consistency"

Thank you.
-uppsax


Daryl Teo

unread,
Jul 29, 2013, 9:55:25 AM7/29/13
to ve...@googlegroups.com
I think, theoretically, you'll find that there is only 1 singleton instance as each instance of the verticle will be using the same classloader.

It isn't safe to depend on singletons in vert.x. Ideally your code should assume the same conditions, regardless of whether you have 5 instances in the same server or 5 instances on 5 separate servers.

Daryl Teo

unread,
Jul 29, 2013, 9:55:49 AM7/29/13
to ve...@googlegroups.com
Should note that you should test this... I'm just speaking theoretically without actually haven't tested it.

uppsax

unread,
Jul 29, 2013, 11:02:48 AM7/29/13
to ve...@googlegroups.com
you'll find that there is only 1 singleton instance as each instance of the verticle will be using the same classloader.

So 5 threads update 1 Singleton simultaneously?

> Ideally your code should assume the same conditions, 

Could you explain a bit more on this?

-uppsax

Daryl Teo

unread,
Jul 29, 2013, 12:01:12 PM7/29/13
to ve...@googlegroups.com
On Tuesday, 30 July 2013 01:02:48 UTC+10, uppsax wrote:
you'll find that there is only 1 singleton instance as each instance of the verticle will be using the same classloader.

So 5 threads update 1 Singleton simultaneously?


I believe so. Perhaps you could run a simple test that updates a single counter and see if you get any race conditions. 
 
> Ideally your code should assume the same conditions, 

Could you explain a bit more on this?

Don't use static if you want to avoid race conditions. Use shared data.

javadevmtl

unread,
Jul 29, 2013, 12:10:15 PM7/29/13
to ve...@googlegroups.com
In 2.X if you use static it can be seen in all verticle instances that are loaded under the same classloader so...

// In your main loader verticle...
container
.deployVerticle("MyVerticle", 5);


// Your actual verticle
class MyVerticle extends Verticle {

     
public static MySingleton mySingleton = MySingleton.getInstance();

     
public void start() {
          mySingleton
.doSomething();

         
// Do some vertx stuff here...
     
}
}





Unless anyone disagrees with me.

uppsax

unread,
Jul 29, 2013, 12:16:33 PM7/29/13
to ve...@googlegroups.com
Thanks everyone, but what I want to do is actually the opposite.

I do NOT want 5 verticles to share data.

How can I have a data structure that holds global valuables for each verticle and verticle A does not mess with global variabes of verticle B?

My issue here is, global variables are fine with on verticle, but with -instances 5 it suddenly that does not work.
Do you have any idea how to do this?
Global variables are evil, but I am porting php code to Java...
-uppsax



uppsax

unread,
Jul 29, 2013, 12:22:13 PM7/29/13
to ve...@googlegroups.com
Or, slightly bigger question... how would you port php code with global variables?
I am having one worker verticle for backend.
Wondering how to hold global variables... it'd be great if I could get rid of those but it seems impossible for me.
What is a good way that works with -instances 5?
Thanks
-uppsax

Daryl Teo

unread,
Jul 29, 2013, 12:31:02 PM7/29/13
to ve...@googlegroups.com
Like I said... use Shared Data. 

Or, have a single separate verticle hold your "global" variables while the rest communicate with it over the EB?

uppsax

unread,
Jul 29, 2013, 12:38:47 PM7/29/13
to ve...@googlegroups.com
> Like I said... use Shared Data. 

I should look into Shared Data now but am I right in saying that Shared Data is for one verticle and that Verticle A does not interfere with Verticle B's shared area?

Thanks
-uppsax

Tim Fox

unread,
Jul 30, 2013, 3:33:33 AM7/30/13
to ve...@googlegroups.com
This depends on whether you're using 1.x or 2.x

The 2.0 classloader model is explained in detail here http://vertx.io/mods_manual.html#module-classloaders

TLDR;

In 1.x each verticle instance gets its own classloader so you would indeed have 5 "singletons".
In 2.x each verticle (type/module) gets its own classloader - here you have 5 instances of the _same_ verticle so they'd share a singleton.

petermd

unread,
Jul 30, 2013, 5:06:04 AM7/30/13
to ve...@googlegroups.com
hi uppsax,

if you want each verticle instance to have its own 'global variables' then you should just be able to make them instance variables of the verticle (not static or singleton) and they will not be shared.

SharedData is shared across the entire VertX instance.

-peter

uppsax

unread,
Jul 30, 2013, 6:25:17 AM7/30/13
to ve...@googlegroups.com
Ok, thank you Tim, I understand.
-uppsax

uppsax

unread,
Jul 30, 2013, 6:29:07 AM7/30/13
to ve...@googlegroups.com
So I will have a non-static variable within verticle class, and then every other class will access the variable, is that what you are saying?  This sounds good.
-uppsax

petermd

unread,
Aug 1, 2013, 10:41:40 AM8/1/13
to ve...@googlegroups.com
hi uppsax,

not sure what you mean. only that instance of the verticle will use that variable, other instances would have their own copy (no sharing). if you want other classes to access that variable also they'd have to access it via a reference to that verticle instance however.

-peter

uppsax

unread,
Aug 8, 2013, 5:19:28 AM8/8/13
to ve...@googlegroups.com
Sorry Peter for replying this late.
I did not notice your reply.

I understood what you are saying.

What I wanted to say is:

-----------
public class SimpleVerticle extends Verticle {

        private GlobalObj  glbl; 

@Override
public void start() {
new A().method(glbl);
new B().method(glbl);
        }
}
class A {
void method(GlobalObj glbl) {
// update glbl
}
}
class B {
void method(GlobalObj glbl) {
// update glbl
}
}
-----------

Say With this, I use "-instances 2".

Global object 'glbl' is confined to verticle.

'glbl's of verticle X and verticle Y are completely independent of each other
and there is no mutual meddling of the data.

Does this sound correct?

Thanks

-uppsax

Jez P

unread,
Aug 8, 2013, 5:39:37 AM8/8/13
to ve...@googlegroups.com
Each instance of the verticle will have its own private data, ie its own instance of GlblObj, and these will be isolated from one another. However, I'm not clear on where your classes A and B fit into the discussion or what you intend them to do, if they have any purpose beyond initializing the global values for each verticle. 

uppsax

unread,
Aug 8, 2013, 5:53:57 AM8/8/13
to ve...@googlegroups.com
Hi

I am porting PHP code and it's got global variables, which are hard to get rid of.
I just needed to have a global point for many classes.
Many classes refer to/update this global variable and do some redis/DB operations using those variables.
As long as instances of verticles do not meddle with each other's global variables, it will be fine...

-uppsax

petermd

unread,
Aug 8, 2013, 6:43:09 AM8/8/13
to ve...@googlegroups.com
hi uppsax,

yes - thats exactly what i was suggesting.

one point that you need to remember however is that while vertx should (!) ensure that any async callbacks (from the eventbus etc) run inside the same verticle instance, there is no guarantee that there are not multiple requests interleaved through that instance. so eg code like

read/write globals
do async then { read/write globals }

will be thread-safe (because each verticle instance can run in parallel while only modifying its own 'globals') but it is not the same as the similar threaded code

read/write globals
dosync
read/write globals

because of the possibility for the verticle instance to run the following sequence with two independent requests scheduled on the same verticle instance

REQ1: read/write globals
REQ1: do async
REQ2: read/write globals
REQ2: do async
REQ2: read/write globals
REQ1: read/write globals

if you need variables scoped to each request then you'll need to create a RequestGlobalsObj to hold a copy of the globals for each request

hope this distinction is obvious

-peter

uppsax

unread,
Aug 9, 2013, 7:50:10 AM8/9/13
to ve...@googlegroups.com
Hi Peter

Thank you for your further thought.

Although I am hoping that I don't have to worry about that.

All my global vars from legacy php are in 'back of the queue'.

Http verticle (front of the queue) does some simple check on json and push it to redis queue.

Several worker verticles created by -instance option (back of the queue) pops json from redis queue and do something about it.  This bit has got global vals.

-uppsax
Reply all
Reply to author
Forward
0 new messages