Pregunta

Estoy tratando de usar SpyMemCached 2.6 con sincronización en la actualización y encontré la siguiente forma de usarlo:

  • Uso de casmutación que define un casmutador que es una forma bastante invasiva de implementarlo, vea un ejemplo:

    public List<Item> addAnItem(final Item newItem) throws Exception {
    
        // This is how we modify a list when we find one in the cache.
        CASMutation<List<Item>> mutation = new CASMutation<List<Item>>() {
    
            // This is only invoked when a value actually exists.
            public List<Item> getNewValue(List<Item> current) {
                // Not strictly necessary if you specify the storage as
                // LinkedList (our initial value isn't), but I like to keep
                // things functional anyway, so I'm going to copy this list
                // first.
                LinkedList<Item> ll = new LinkedList<Item>(current);
    
                // If the list is already "full", pop one off the end.
                if(ll.size() > 10) {
                    ll.removeLast();
                }
                // Add mine first.
                ll.addFirst(newItem);
    
                return ll;
            }
        };
    
        // The initial value -- only used when there's no list stored under
        // the key.
        List<Item> initialValue=Collections.singletonList(newItem);
    
        // The mutator who'll do all the low-level stuff.
        CASMutator<List<Item>> mutator = new CASMutator<List<Item>>(client, transcoder);
    
        // This returns whatever value was successfully stored within the
        // cache -- either the initial list as above, or a mutated existing
        // one
        return mutator.cas("myKey", initialValue, 0, mutation);
    }
    

o usando cas método

cas(String key, long casId, Object value)

Después de haber hecho:

gets(String key, Transcoder<T> tc) 

El segundo es realmente más simple, y entiendo por qué usaría la casmutación ... Me complacería mucho recibir comentarios sobre el uso de este cliente de Couchbase.

¿Fue útil?

Solución

Casmutator/Casmutation captura las mejores prácticas y el flujo de trabajo para que lo correcto se haga por usted.

Tu contra-examen aspecto más simple ya que no estás diciendo lo que realmente hacer con esos métodos. La muestra que publicó anteriormente muestra una lista que se saca de Memcached, un nuevo elemento agregado, eliminando condicionalmente algunos elementos de él y luego devolviéndolo. Al menos la mitad de ese texto que publicaste, aún necesitarías escribir.

Si no lo haces usar Casmutador, terminarás reinventándolo, y eso no es tan simple. Esto es lo que hace por ti hoy:

public T cas(final String key, final T initial, int initialExp,
        final CASMutation<T> m) throws Exception {
    T rv=initial;

    boolean done=false;
    for(int i=0; !done && i<max; i++) {
        CASValue<T> casval=client.gets(key, transcoder);
        T current=null;
        // If there were a CAS value, check to see if it's compatible.
        if(casval != null) {
            T tmp = casval.getValue();
            current=tmp;
        }
        // If we have anything mutate and CAS, else add.
        if(current != null) {
            // Declaring this impossible since the only way current can
            // be non-null is if casval was set.
            assert casval != null : "casval was null with a current value";

            rv=m.getNewValue(current);
            // There are three possibilities here:
            //  1) It worked and we're done.
            //  2) It collided and we need to reload and try again.
            //  3) It disappeared between our fetch and our cas.
            // We're ignoring #3 because it's *extremely* unlikely and the
            // behavior will be fine in this code -- we'll do another gets
            // and follow it up with either an add or another cas depending
            // on whether it exists the next time.
            if(client.cas(key, casval.getCas(), rv, transcoder)
                    == CASResponse.OK) {
                done=true;
            }
        } else {
            // No value found, try an add.
            if(initial == null) {
                done = true;
                rv = null;
            } else if(client.add(key, initialExp, initial, transcoder).get()) {
                done=true;
                rv=initial;
            }
        }
    }
    if(!done) {
        throw new RuntimeException("Couldn't get a CAS in " + max
            + " attempts");
    }

    return rv;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top