简体   繁体   English

LoadableDetachableModel多线程问题

[英]LoadableDetachableModel multi-threading issue

We had an issue where a lot of users were hitting a page that had a lot of ajax calls on it. 我们遇到了一个问题,即许多用户访问的页面上有很多ajax调用。 It took us a long time to run down and we finally found a threading issue in LoadableDetachableModel. 我们花了很长的时间才能运行,最终我们在LoadableDetachableModel中发现了一个线程问题。

I think the problem is related to the fact that we have a UserModel in the Session. 我认为问题与Session中有一个UserModel有关。 This UserModel extends LoadableDetachableModel. 此UserModel扩展了LoadableDetachableModel。 If the load() method takes too long to return then a second Thread could get a null User returned based on the fact that the attached flag is set to true before load() is called and before transientModelObject is set. 如果load()方法花费的时间太长,无法返回,则第二个线程可能会返回空用户,这是基于以下事实:在load()被调用之前和transientModelObject被设置之前,附加标志被设置为true。 To fix it we simply made our own modified version of LoadableDetachableModel that added synchronization where necessary. 为了解决这个问题,我们仅制作了自己的LoadableDetachableModel修改版,在必要时添加了同步。 Since then we have had no more problems. 从那时起,我们再也没有问题了。

I looked around in the Wicket Jira site and even looked at some commits within fisheye to see if this issue had been fixed because I noticed Wicket 7 does not have an attached flag. 我在Wicket Jira站点中四处查看,甚至查看了鱼眼中的一些提交,以查看此问题是否已解决,因为我注意到Wicket 7没有附加的标志。 Instead it has an enum called InternalState to fix WICKET-5916. 相反,它有一个名为InternalState的枚举来修复WICKET-5916。 It appears the threading issue is still present in the 7.2 version of wicket. 似乎在7.2版的wicket中仍然存在线程问题。 Here is the code: 这是代码:

    @Override
public final T getObject()
{
    if (state == null || state == InternalState.DETACHED)
    {
        // prevent infinite attachment loops
        state = InternalState.ATTACHING;//<--One thread sets this, next thread gets a null object returned since load() has not completed

        transientModelObject = load();

        if (log.isDebugEnabled())
        {
            log.debug("loaded transient object " + transientModelObject + " for " + this +
                ", requestCycle " + RequestCycle.get());
        }

        state = InternalState.ATTACHED;
        onAttach();
    }
    return transientModelObject;
}

As you can see, if a single thread calls getObject() and gets to the line calling load() then the model has the state variable set to ATTACHING. 如您所见,如果单个线程调用getObject()并到达调用load()的行,那么该模型会将状态变量设置为ATTACHING。 Now, the next thread calls getObject() before the load() completes and gets a null object returned since state is not null and state is not DETACHED. 现在,下一个线程在load()完成之前调用getObject(),并返回一个空对象,因为state不为null且state为DETACHED。

Again, I think this could only happen if you are using a LoadableDetachableModel in your Session or Application class where multiple threads could reuse the same model. 同样,我认为只有在您的Session或Application类中使用LoadableDetachableModel时,才会发生这种情况,在该类中,多个线程可以重用同一模型。

Am I missing something or should I file a bug report? 我是否缺少某些东西,还是应该提交错误报告? Should I not be using a LoadableDetachableModel in the Session? 我不应该在会话中使用LoadableDetachableModel吗?

IModel is an interface to be used by Components, and all components are single-threaded. IModel是组件要使用的接口,并且所有组件都是单线程的。 Don't use a model in your session or application. 不要在会话或应用程序中使用模型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM