Java 如何在使用vertx3更新的数据库查询之上创建异步缓存

Java 如何在使用vertx3更新的数据库查询之上创建异步缓存,java,mongodb,caching,asynchronous,vert.x,Java,Mongodb,Caching,Asynchronous,Vert.x,下面是一个关于如何使用asyncvertx mongo client在数据库顶部使用内存缓存的示例。它尽可能的简约。它是完全可执行的,上面有重要的东西 不幸的是,在建立缓存条目时,没有任何东西可以阻止对同一密钥的多个数据库访问和缓存插入。使用标准锁定机制是不可能的,因为它会阻止事件循环 我需要一个异步缓存和数据库调用,以便在第一个实际命中db的调用之后,cache.get()调用将“返回到事件循环”(我可以这么说吗?),并“等待”缓存项变为可用。(多么可怕的一句话,我道歉) 我如何做到这一点?我

下面是一个关于如何使用async
vertx mongo client
在数据库顶部使用内存缓存的示例。它尽可能的简约。它是完全可执行的,上面有重要的东西

不幸的是,在建立缓存条目时,没有任何东西可以阻止对同一密钥的多个数据库访问和缓存插入。使用标准锁定机制是不可能的,因为它会阻止事件循环

我需要一个异步缓存和数据库调用,以便在第一个实际命中db的调用之后,
cache.get()
调用将“返回到事件循环”(我可以这么说吗?),并“等待”缓存项变为可用。(多么可怕的一句话,我道歉)

我如何做到这一点?我正在考虑学习一些
vertx
模块源代码,例如
vertxmongo客户端
,以了解如何实现。但如果有人能在这里提供答案,那就太好了

package q;

import io.vertx.core.AbstractVerticle;
import io.vertx.core.Vertx;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.mongo.MongoClient;

import java.util.HashMap;
import java.util.Map;

public class ExampleVerticle extends AbstractVerticle
{
  @Override
  public void start() throws Exception {
    MongoClient mongoClient = MongoClient.createShared(vertx, new JsonObject().put("db_name", "example_db"));
    SomeCache cache = new SomeCache();

    vertx.eventBus().consumer("sesame_street", messageHandler -> {
      Integer lookUpKey = Integer.valueOf(messageHandler.body().toString());
      JsonObject result = cache.get(lookUpKey);

      if(result != null) {
        messageHandler.reply(result);
        System.out.println("Was served from cache");
      } else {
        mongoClient.findOne("example_collection", new JsonObject().put("_id", lookUpKey),
                new JsonObject(), resultHandler -> {
                  if(resultHandler.succeeded()) {
                    messageHandler.reply(resultHandler.result());
                    cache.put(lookUpKey, resultHandler.result());
                    System.out.println("Value stored in cache");
                  } else {
                    messageHandler.fail(0xBADC0DE, resultHandler.cause().toString());
                  }
                });
      }
    });
  }

  static class SomeCache
  {
    Map<Integer, JsonObject> elMapa = new HashMap<>();

    public void put(Integer key, JsonObject value) {
      elMapa.put(key, value);
    }

    public JsonObject get(Integer key) {
      return elMapa.get(key);
    }
  }

  public static void main(String[] args) {
    Vertx vertx = Vertx.vertx();
    vertx.deployVerticle(new ExampleVerticle(), completionHandler -> {
      if(completionHandler.succeeded()) {
        vertx.eventBus().send("sesame_street", 1, replyHandler -> {
          if(replyHandler.succeeded()) {
            //Comment out this println and you'll maybe see 'Value stored in cache' twice in the console output.
            System.out.println("Yes! " + replyHandler.result().body());
            vertx.eventBus().send("sesame_street", 1);
          }
          vertx.close();
        });
      }
    });
  }
}
q包;
导入io.vertx.core.AbstractVerticle;
导入io.vertx.core.vertx;
导入io.vertx.core.json.JsonObject;
导入io.vertx.ext.mongo.MongoClient;
导入java.util.HashMap;
导入java.util.Map;
公共类ExampleVerticle扩展了AbstractVerticle
{
@凌驾
public void start()引发异常{
MongoClient MongoClient=MongoClient.createShared(vertx,newjsonobject().put(“db_name”,“example_db”);
SomeCache=newsomecache();
vertx.eventBus().consumer(“芝麻街”,messageHandler->{
整数lookUpKey=Integer.valueOf(messageHandler.body().toString());
JsonObject result=cache.get(lookUpKey);
如果(结果!=null){
messageHandler.reply(结果);
System.out.println(“从缓存中提供”);
}否则{
findOne(“示例集合”,新JsonObject().put(“\u id”,lookUpKey)),
新建JsonObject(),resultHandler->{
if(resultHandler.successed()){
reply(resultHandler.result());
cache.put(lookUpKey,resultHandler.result());
System.out.println(“存储在缓存中的值”);
}否则{
messageHandler.fail(0xBADC0DE,resultHandler.cause().toString());
}
});
}
});
}
静态类缓存
{
Map elMapa=newhashmap();
公共void put(整数键,JsonObject值){
elMapa.put(键、值);
}
公共JsonObject get(整数键){
返回elMapa.get(键);
}
}
公共静态void main(字符串[]args){
Vertx Vertx=Vertx.Vertx();
deployVerticle(新示例Verticle(),completionHandler->{
if(completionHandler.successed()){
vertx.eventBus().send(“芝麻街”,1,replyHandler->{
if(replyHandler.successed()){
//注释掉这个println,您可能会在控制台输出中看到两次“值存储在缓存中”。
System.out.println(“Yes!”+replyHandler.result().body());
vertx.eventBus().send(“芝麻街”,1);
}
vertx.close();
});
}
});
}
}

Vertx具有
异步锁的概念。这不会阻塞,但会在获取处理程序时调用带有锁的处理程序

看看:


Vertx具有
异步锁的概念。这不会阻塞,但会在获取处理程序时调用带有锁的处理程序

看看:


谢谢你的回答。不幸的是,我还没有时间去调查。也许一周左右吧。谢谢你的回答。不幸的是,我还没有时间去调查。大概一周左右吧。