从Firestore事务中使用MemcacheService的异常

时间:2018-08-30 09:07:10

标签: java google-app-engine google-cloud-firestore

最近开始了一个新项目,并决定将Cloud Firestore与GAE Standard(Java 8)结合使用。我正在使用GAE Standard的内置MemcacheService来提高性能。

只是开始玩交易。简单的交易场景:

  1. 获取一个User
  2. user的点更新1。
  3. 保存User

以下是一些代码:

//Somewhere on the main request thread
public static final MemcacheService CACHE = MemcacheServiceFactory.getMemcacheService(NAMESPACE);
.
.
.    
DocumentReference ref = // assignment
UserRepository userRep = UserRepository.get();
User usr = userRep.get(ref).orElse(null); // for comparison purposes
// Log pre-transaction values
try {
    usr = db().<User>runTransaction((Transaction tx) -> {
        User user = userRep.get(ref, tx).orElse(null);
        user.setPoints(user.getPoints() + 1);
        userRep.save(user, tx);
        return user;
    }).get();
} catch (InterruptedException | ExecutionException | RuntimeException e) {
    log().log(Level.WARNING, "Unexpected error!", e);
}
// Log post-transaction values

效果很好(如预期的那样),但是我的MemcacheService现在有了陈旧的数据。因此,在我的UserRepository.save(User, Transaction)方法中,我添加了一个调用以删除缓存的版本:

public WriteResult save(@Nullable T obj, Transaction tx) throws IllegalArgumentException, SaveException {
    if (null != obj) {
        if (null != tx && null != obj.getId()) {
            DocumentReference ref = this.collRef.document(obj.getId());
            tx.set(ref, obj);
            CACHE.delete(ref.getPath()); // adding this line causes the exception
        } else {
            return save(obj); // throws IllegalArgumentException, SaveException
        }
    }
    return null;
}

现在我开始得到异常:

WARNING: Unexpected error!
java.util.concurrent.ExecutionException: com.google.apphosting.api.ApiProxy$CallNotFoundException: Can't make API call memcache.Delete in a thread that is neither the original request thread nor a thread created by ThreadManager
    at com.google.common.util.concurrent.AbstractFuture.getDoneValue(AbstractFuture.java:531)
    at com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture.java:512)
    at com.google.api.core.AbstractApiFuture.get(AbstractApiFuture.java:56)
    at com.example.testapp.servlets.Users.updatePoints(Users.java:98)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.example.testapp.servlets.EntryServlet.defaultMapping(EntryServlet.java:221)
    at com.example.testapp.servlets.EntryServlet.doGet(EntryServlet.java:113)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:848)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1772)
    at com.google.appengine.tools.development.ResponseRewriterFilter.doFilter(ResponseRewriterFilter.java:134)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1759)
    at com.google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:34)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1759)
    at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:63)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1759)
    at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:48)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1759)
    at com.google.appengine.tools.development.jetty9.StaticFileFilter.doFilter(StaticFileFilter.java:123)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1759)
    at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectRequest(DevAppServerModulesFilter.java:366)
    at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectModuleRequest(DevAppServerModulesFilter.java:349)
    at com.google.appengine.tools.development.DevAppServerModulesFilter.doFilter(DevAppServerModulesFilter.java:116)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1759)
    at com.google.appengine.tools.development.DevAppServerRequestLogFilter.doFilter(DevAppServerRequestLogFilter.java:44)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1751)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:582)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:524)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1180)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:512)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1112)
    at com.google.appengine.tools.development.jetty9.DevAppEngineWebAppContext.doScope(DevAppEngineWebAppContext.java:94)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)
    at com.google.appengine.tools.development.jetty9.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:601)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)
    at org.eclipse.jetty.server.Server.handle(Server.java:534)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:320)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:283)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:108)
    at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93)
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.executeProduceConsume(ExecuteProduceConsume.java:303)
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:148)
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:136)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589)
    at java.lang.Thread.run(Thread.java:748)
Caused by: com.google.apphosting.api.ApiProxy$CallNotFoundException: Can't make API call memcache.Delete in a thread that is neither the original request thread nor a thread created by ThreadManager
    at com.google.apphosting.api.ApiProxy$CallNotFoundException.foreignThread(ApiProxy.java:844)
    at com.google.apphosting.api.ApiProxy$1.get(ApiProxy.java:183)
    at com.google.apphosting.api.ApiProxy$1.get(ApiProxy.java:180)
    at com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:89)
    at com.google.appengine.api.memcache.MemcacheServiceImpl.quietGet(MemcacheServiceImpl.java:26)
    at com.google.appengine.api.memcache.MemcacheServiceImpl.delete(MemcacheServiceImpl.java:120)
    at com.example.testapp.data.Cache.delete(Cache.java:52)
    at com.example.testapp.data.FirestoreRepository.save(FirestoreRepository.java:203)
    at com.example.testapp.servlets.Users.lambda$0(Users.java:96)
    at com.google.cloud.firestore.FirestoreImpl$2$2.run(FirestoreImpl.java:350)
    at io.grpc.Context$1.run(Context.java:595)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    ... 1 more

我正在运行在开发服务器上(使用GCP Eclipse插件)以及部署到GAE时的异常。

0 个答案:

没有答案