Vert.x SharedData - can it reliably store an LRU?

44 views Asked by At

I'm trying to store a list of things in the Vert.x cluster shared data, where the list if kind of like a queue, but things drop off of the queue based on a limit of number of elements - basically the same thing as a LinkedHashMap with a removeEldestEntry() implementation.

I've noticed that the main data storage facility in Vert.x SharedData is AsyncMap - where I can store a list in one of the values, but as far as I understand, if I have concurrent writers - then there will be data loss: unless I lock the map before and during each update - because if the storage mechanism is a list in a map entry, I will need to mutate the map value.

Is there another mechanism to store a mutable list in Vert.x SharedData that needs less locking?

I rather not get into needing a "real database" situation, because the system currently has none and I hoped to continue avoiding that for a little while longer.

1

There are 1 answers

0
Guss On

As per the comments discussion, it appears that the only way to safely and consistently store and retrieve data to the Vert.x SharedData AsyncMap API is to lock around any access that is more complex then "single put" or "single get". So my current implementation looks like this:

/* This example stores strings for simplicity */
public Future<Void> addValue(String value) {
  return sharedData.getLock(SHARED_LOCK)
    .compose(lock -> sharedData.<String, List<String>>getAsyncMap(SHARED_DATA)
      .compose(map -> map.get(SHARED_KEY)
        .onSuccess(l -> l.add(value))
        .onSuccess(l -> {
          while (l.size() > MAX_SIZE)
            l.remove(0);
        })
        .compose(l -> map.put(SHARED_KEY, l))
      )
      .onComplete(__ -> lock.release())
    );
}

I would love to hear a better suggestion, because using a map to store a single list seems to me like a bad design.

Also, I didn't cover initializing the list at the first place - it should be trivial but complicates an already too complicated example, so I skipped that.