You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by Dionis Argiri <di...@gmail.com> on 2012/04/25 10:53:15 UTC

Struts2 session concurrency issue ?

Hi!

I have some troubles (with understanding?) how session works.

For example, I have two actions: First and Second.

I have written simple utility, that uses executor service to send 100000
asynchronous requests to action Second.

In First action (which is called only from my browser) I do:

HitCounter.increment();
ActionContext.getContext().getSession().put("counter",
HitCounter.getAtomicCounter());
return Action.SUCCESS;

In second action I do:

System.out.println("From session:
"+ActionContext.getContext().getSession().get("counter"));
System.out.println("Actual:"+ HitCounter.getAtomicCounter());
return Action.SUCCESS;

And the output I see(and it really makes me mad):

>From session: 2
Actual: 69352

After some time when I use this Fitst action/Second action only from my
browsers and no concurrent requests come(generated by my load utility),
results "are stabilized" to actual values. Thus, it seems that I have
concurrency issues with session or I'm missing some points.

Is there a standard way that I should use to solve this problem, when using
Struts2 ?

P.S. HitCounter realisation:

public class HitCounter {
    private static AtomicInteger counter = new AtomicInteger(0);

    public static void increment() {
        counter.incrementAndGet();
    }
    public static int getAtomicCounter() {
        return counter.get();
    }
}

BR,

Dionis

Re: Struts2 session concurrency issue ?

Posted by Dionis Argiri <di...@gmail.com>.
No, my utility don't remember session id. Probably it's the problem. Then
I'll need to rewrite my utility code, so that it handles it the right
way(setting cookies in headers).

Ok, but another question is whether or not Map that I get when calling
ActionContext.getContext().getSession() is thread safe?

P.S. AtomicInteger makes increment/decrement operations thread safe. Like
if you would put synchronized on each method. But it makes it a little bit
in more efficient way.

25 апреля 2012 г. 13:24 пользователь Aaron Brown
<aa...@thebrownproject.com>написал:

> To answer, I think we need to know more about your utility program that
> triggers action 2. Sessions are tracked through a cookie containing a
> JSESSIONID. Does your utility retain cookies so that each page load will
> reference the same session? Also, does your utility wait for each page to
> complete before requesting again? You said "asynchronous" but your code
> does not look thread safe to me. (I have never used atomicinteger before so
> never mind if that class somehow handles thread safety for you)
>
> Aaron
>  On Apr 25, 2012 5:11 AM, "Dionis Argiri" <di...@gmail.com> wrote:
>
> > What is the difference between using
> > ActionContext.getContext().getSession() vs implementing SessionAware
> > interface? Does it give some advantages?
> >
> > 25 апреля 2012 г. 12:01 пользователь Łukasz Lenart <
> > lukasz.lenart@googlemail.com> написал:
> >
> > > Why don't you use SessesionAware interface ?
> > >
> > >
> > > Regards
> > > --
> > > Łukasz http://www.lenart.org.pl/
> > > mobile +48 606 323 122, office +27 11 0838747
> > > Warszawa JUG conference - Confitura http://confitura.pl/
> > >
> > > ---------------------------------------------------------------------
> > > To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> > > For additional commands, e-mail: user-help@struts.apache.org
> > >
> > >
> >
>

Re: Struts2 session concurrency issue ?

Posted by Aaron Brown <aa...@thebrownproject.com>.
To answer, I think we need to know more about your utility program that
triggers action 2. Sessions are tracked through a cookie containing a
JSESSIONID. Does your utility retain cookies so that each page load will
reference the same session? Also, does your utility wait for each page to
complete before requesting again? You said "asynchronous" but your code
does not look thread safe to me. (I have never used atomicinteger before so
never mind if that class somehow handles thread safety for you)

Aaron
 On Apr 25, 2012 5:11 AM, "Dionis Argiri" <di...@gmail.com> wrote:

> What is the difference between using
> ActionContext.getContext().getSession() vs implementing SessionAware
> interface? Does it give some advantages?
>
> 25 апреля 2012 г. 12:01 пользователь Łukasz Lenart <
> lukasz.lenart@googlemail.com> написал:
>
> > Why don't you use SessesionAware interface ?
> >
> >
> > Regards
> > --
> > Łukasz http://www.lenart.org.pl/
> > mobile +48 606 323 122, office +27 11 0838747
> > Warszawa JUG conference - Confitura http://confitura.pl/
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> > For additional commands, e-mail: user-help@struts.apache.org
> >
> >
>

Re: Struts2 session concurrency issue ?

Posted by Łukasz Lenart <lu...@googlemail.com>.
2012/4/25 Dionis Argiri <di...@gmail.com>:
> What is the difference between using ActionContext.getContext().getSession()
> vs implementing SessionAware interface? Does it give some advantages?

That's the proper way to interact with session, ActionContext
shouldn't be used by user, it's only for internal use.

http://struts.apache.org/2.x/docs/http-session.html


Regards
-- 
Łukasz http://www.lenart.org.pl/
mobile +48 606 323 122, office +27 11 0838747
Warszawa JUG conference - Confitura http://confitura.pl/

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org


Re: Struts2 session concurrency issue ?

Posted by Dionis Argiri <di...@gmail.com>.
What is the difference between using
ActionContext.getContext().getSession() vs implementing SessionAware
interface? Does it give some advantages?

25 апреля 2012 г. 12:01 пользователь Łukasz Lenart <
lukasz.lenart@googlemail.com> написал:

> Why don't you use SessesionAware interface ?
>
>
> Regards
> --
> Łukasz http://www.lenart.org.pl/
> mobile +48 606 323 122, office +27 11 0838747
> Warszawa JUG conference - Confitura http://confitura.pl/
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
>
>

Re: Struts2 session concurrency issue ?

Posted by Łukasz Lenart <lu...@googlemail.com>.
Why don't you use SessesionAware interface ?


Regards
-- 
Łukasz http://www.lenart.org.pl/
mobile +48 606 323 122, office +27 11 0838747
Warszawa JUG conference - Confitura http://confitura.pl/

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: Struts2 session concurrency issue ?

Posted by Dionis Argiri <di...@gmail.com>.
Actual problem was with my load testing utility. I have not used jsessionid
and thus it was causing the "problem". Also I have took a look at source
code. When calling ActionContext.getContext().getSession() -
SessionMap<String, Object> is returned. It is a map, that wraps session and
uses synchronization on it. Thus it's a thread safe realisation. Anyway,
thank you for the support.

26 апреля 2012 г. 1:32 пользователь Rene Gielen
<re...@googlemail.com>написал:

> Please remember that the HTTP session is not synchronized. Thus, using the
> session.put is a critical method. Most likely, what you really want to do
> is
> counter = session.get("counter");
> counter.increment (or incrementAndGet)
> In this way you ensure exactly the same object is accessed and incremted /
> consumed.
>
> On Wed, Apr 25, 2012 at 4:03 PM, Gabriel Belingueres
> <be...@gmail.com>wrote:
>
> > The "S2 way" of accessing the session is implementing the SessionAware
> > interface.
> >
> > First you must realize that what you are putting on session scope is
> > not the AtomicInteger per se, but its current value at the moment you
> > call the first action, so unless you call the first action again, the
> > value stored in session will NOT change.
> > The second action does not change the value in session, just print
> > what was already stored.
> >
> > When you said that after some time, the results are "stabilized", I
> > guess that you are requesting the first action after no other request
> > is running so you get the current value again and then call the second
> > action serially, giving you the same value.
> >
> > Also, you have concurrency issues if the first action:
> >
> > HitCounter.increment();
> > ActionContext.getContext().getSession().put("counter",
> > HitCounter.getAtomicCounter());
> >
> > you increment without returning the new value. Instead you call the
> > getAtomicCounter() method, which will cause interference between
> > threads (ie not thread safe), if the point that every session have a
> > different counter value, then you must change the increment method
> > like this:
> >   public static int increment() {
> >       return counter.incrementAndGet();
> >   }
> > and use that value to store it in session (no call to
> getAtomicCounter()).
> >
> > HTH,
> > Gabriel
> >
> > 2012/4/25 Dionis Argiri <di...@gmail.com>:
> > > Hi!
> > >
> > > I have some troubles (with understanding?) how session works.
> > >
> > > For example, I have two actions: First and Second.
> > >
> > > I have written simple utility, that uses executor service to send
> 100000
> > > asynchronous requests to action Second.
> > >
> > > In First action (which is called only from my browser) I do:
> > >
> > > HitCounter.increment();
> > > ActionContext.getContext().getSession().put("counter",
> > > HitCounter.getAtomicCounter());
> > > return Action.SUCCESS;
> > >
> > > In second action I do:
> > >
> > > System.out.println("From session:
> > > "+ActionContext.getContext().getSession().get("counter"));
> > > System.out.println("Actual:"+ HitCounter.getAtomicCounter());
> > > return Action.SUCCESS;
> > >
> > > And the output I see(and it really makes me mad):
> > >
> > > From session: 2
> > > Actual: 69352
> > >
> > > After some time when I use this Fitst action/Second action only from my
> > > browsers and no concurrent requests come(generated by my load utility),
> > > results "are stabilized" to actual values. Thus, it seems that I have
> > > concurrency issues with session or I'm missing some points.
> > >
> > > Is there a standard way that I should use to solve this problem, when
> > using
> > > Struts2 ?
> > >
> > > P.S. HitCounter realisation:
> > >
> > > public class HitCounter {
> > >    private static AtomicInteger counter = new AtomicInteger(0);
> > >
> > >    public static void increment() {
> > >        counter.incrementAndGet();
> > >    }
> > >    public static int getAtomicCounter() {
> > >        return counter.get();
> > >    }
> > > }
> > >
> > > BR,
> > >
> > > Dionis
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> > For additional commands, e-mail: user-help@struts.apache.org
> >
> >
>

Re: Struts2 session concurrency issue ?

Posted by Rene Gielen <re...@googlemail.com>.
Please remember that the HTTP session is not synchronized. Thus, using the
session.put is a critical method. Most likely, what you really want to do is
counter = session.get("counter");
counter.increment (or incrementAndGet)
In this way you ensure exactly the same object is accessed and incremted /
consumed.

On Wed, Apr 25, 2012 at 4:03 PM, Gabriel Belingueres
<be...@gmail.com>wrote:

> The "S2 way" of accessing the session is implementing the SessionAware
> interface.
>
> First you must realize that what you are putting on session scope is
> not the AtomicInteger per se, but its current value at the moment you
> call the first action, so unless you call the first action again, the
> value stored in session will NOT change.
> The second action does not change the value in session, just print
> what was already stored.
>
> When you said that after some time, the results are "stabilized", I
> guess that you are requesting the first action after no other request
> is running so you get the current value again and then call the second
> action serially, giving you the same value.
>
> Also, you have concurrency issues if the first action:
>
> HitCounter.increment();
> ActionContext.getContext().getSession().put("counter",
> HitCounter.getAtomicCounter());
>
> you increment without returning the new value. Instead you call the
> getAtomicCounter() method, which will cause interference between
> threads (ie not thread safe), if the point that every session have a
> different counter value, then you must change the increment method
> like this:
>   public static int increment() {
>       return counter.incrementAndGet();
>   }
> and use that value to store it in session (no call to getAtomicCounter()).
>
> HTH,
> Gabriel
>
> 2012/4/25 Dionis Argiri <di...@gmail.com>:
> > Hi!
> >
> > I have some troubles (with understanding?) how session works.
> >
> > For example, I have two actions: First and Second.
> >
> > I have written simple utility, that uses executor service to send 100000
> > asynchronous requests to action Second.
> >
> > In First action (which is called only from my browser) I do:
> >
> > HitCounter.increment();
> > ActionContext.getContext().getSession().put("counter",
> > HitCounter.getAtomicCounter());
> > return Action.SUCCESS;
> >
> > In second action I do:
> >
> > System.out.println("From session:
> > "+ActionContext.getContext().getSession().get("counter"));
> > System.out.println("Actual:"+ HitCounter.getAtomicCounter());
> > return Action.SUCCESS;
> >
> > And the output I see(and it really makes me mad):
> >
> > From session: 2
> > Actual: 69352
> >
> > After some time when I use this Fitst action/Second action only from my
> > browsers and no concurrent requests come(generated by my load utility),
> > results "are stabilized" to actual values. Thus, it seems that I have
> > concurrency issues with session or I'm missing some points.
> >
> > Is there a standard way that I should use to solve this problem, when
> using
> > Struts2 ?
> >
> > P.S. HitCounter realisation:
> >
> > public class HitCounter {
> >    private static AtomicInteger counter = new AtomicInteger(0);
> >
> >    public static void increment() {
> >        counter.incrementAndGet();
> >    }
> >    public static int getAtomicCounter() {
> >        return counter.get();
> >    }
> > }
> >
> > BR,
> >
> > Dionis
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
>
>

Re: Struts2 session concurrency issue ?

Posted by Gabriel Belingueres <be...@gmail.com>.
The "S2 way" of accessing the session is implementing the SessionAware
interface.

First you must realize that what you are putting on session scope is
not the AtomicInteger per se, but its current value at the moment you
call the first action, so unless you call the first action again, the
value stored in session will NOT change.
The second action does not change the value in session, just print
what was already stored.

When you said that after some time, the results are "stabilized", I
guess that you are requesting the first action after no other request
is running so you get the current value again and then call the second
action serially, giving you the same value.

Also, you have concurrency issues if the first action:

HitCounter.increment();
ActionContext.getContext().getSession().put("counter",
HitCounter.getAtomicCounter());

you increment without returning the new value. Instead you call the
getAtomicCounter() method, which will cause interference between
threads (ie not thread safe), if the point that every session have a
different counter value, then you must change the increment method
like this:
   public static int increment() {
       return counter.incrementAndGet();
   }
and use that value to store it in session (no call to getAtomicCounter()).

HTH,
Gabriel

2012/4/25 Dionis Argiri <di...@gmail.com>:
> Hi!
>
> I have some troubles (with understanding?) how session works.
>
> For example, I have two actions: First and Second.
>
> I have written simple utility, that uses executor service to send 100000
> asynchronous requests to action Second.
>
> In First action (which is called only from my browser) I do:
>
> HitCounter.increment();
> ActionContext.getContext().getSession().put("counter",
> HitCounter.getAtomicCounter());
> return Action.SUCCESS;
>
> In second action I do:
>
> System.out.println("From session:
> "+ActionContext.getContext().getSession().get("counter"));
> System.out.println("Actual:"+ HitCounter.getAtomicCounter());
> return Action.SUCCESS;
>
> And the output I see(and it really makes me mad):
>
> From session: 2
> Actual: 69352
>
> After some time when I use this Fitst action/Second action only from my
> browsers and no concurrent requests come(generated by my load utility),
> results "are stabilized" to actual values. Thus, it seems that I have
> concurrency issues with session or I'm missing some points.
>
> Is there a standard way that I should use to solve this problem, when using
> Struts2 ?
>
> P.S. HitCounter realisation:
>
> public class HitCounter {
>    private static AtomicInteger counter = new AtomicInteger(0);
>
>    public static void increment() {
>        counter.incrementAndGet();
>    }
>    public static int getAtomicCounter() {
>        return counter.get();
>    }
> }
>
> BR,
>
> Dionis

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org