-
Notifications
You must be signed in to change notification settings - Fork 140
[Z Design Doc] Cache API
KVStore API.
There is a new kvstore/cache API.
It consists of two interface.
- KeyValueStoreService Object interface to store objects into a cache using some sort of encoding.
- LowLevelKeyValueStoreService Low level kv store to store strings or byte arrays
LowLevelKeyValueStoreService
works with byte arrays and Strings.
The LowLevelKeyValueStoreService
is for low-level cache access.
package io.advantageous.qbit.kvstore;
import io.advantageous.qbit.reactive.Callback;
import io.advantageous.qbit.time.Duration;
import java.util.Optional;
/** Low level key value store with expiration timeout. */
public interface LowLevelKeyValueStoreService {
/**
* Store a string value in the kv store.
* @param key key
* @param value value
*/
void putString(final String key, final String value);
/**
* Store a string value and get a confirmation that it was stored.
* @param confirmation confirmation
* @param key key
* @param value value
*/
void putStringWithConfirmation(final Callback<Boolean> confirmation,
final String key,
final String value);
/**
* Store a key value with an expiry.
* @param confirmation confirmation
* @param key key
* @param value value
* @param expiry expiry
*/
void putStringWithConfirmationAndTimeout(
final Callback<Boolean> confirmation,
final String key,
final String value,
final Duration expiry);
/**
* Store a key value with a timeout expiry.
* @param key key
* @param value value
* @param expiry expiry
*/
void putStringWithTimeout(
final String key,
final String value,
final Duration expiry);
/**
* Get a String key value.
* @param confirmation confirmation
* @param key key
*/
void getString( final Callback<Optional<String>> confirmation,
final String key);
/**
* Store a byte array value in the kv store.
* @param key key
* @param value value
*/
void putBytes( final String key,
final byte[] value);
/**
* Store a byte array value in the kv store with a confirmation callback.
* @param confirmation confirmation
* @param key key
* @param value value
*/
void putBytesWithConfirmation( final Callback<Boolean> confirmation,
final String key,
final byte[] value);
/**
* Store a byte array value in the kv store with a
* confirmation callback and expiry.
* @param confirmation confirmation
* @param key key
* @param value value
* @param expiry expiry
*/
void putBytesWithConfirmationAndTimeout( final Callback<Boolean> confirmation,
final String key,
final byte[] value,
final Duration expiry);
/**
* Store a byte array with an expiry.
* @param key key
* @param value value
* @param expiry expiry
*/
void putBytesWithTimeout( final String key,
final byte[] value,
final Duration expiry);
/**
* Get a byte array value given the key.
* @param callback callback
* @param key key
*/
void getBytes( final Callback<Optional<byte[]>> callback,
final String key);
/**
* Check to see if the store has the key
* @param hasKeyCallback hasKeyCallback
* @param key key
*/
void hasKey( final Callback<Boolean> hasKeyCallback,
final String key);
/**
* Delete the key.
* @param key key
*/
void delete(final String key);
/**
* Delete the key with confirmation.
* @param key key
*/
void deleteWithConfirmation( final Callback<Boolean> confirmation,
final String key);
void process();
}
The low level KV store defines a contract to save things as byte[] or String. The String can be used to save objects as JSON objects. The byte[] can be used to save serialized objects.
The KeyValueStoreService<T>
is used to store objects.
package io.advantageous.qbit.kvstore;
import io.advantageous.qbit.reactive.Callback;
import io.advantageous.qbit.time.Duration;
import java.util.Optional;
/**
*
* @param <T> T
*/
public interface KeyValueStoreService<T> {
/**
* Store a value in the kv store.
* @param key key
* @param value value
*/
void put(final String key, final T value);
/**
* Store a value and get a confirmation that it was stored.
* @param confirmation confirmation
* @param key key
* @param value value
*/
void putWithConfirmation(final Callback<Boolean> confirmation,
final String key,
final T value);
/**
* Store a key value with an expiry ad confirmation.
* @param confirmation confirmation
* @param key key
* @param value value
* @param expiry expiry
*/
void putWithConfirmationAndTimeout(
final Callback<Boolean> confirmation,
final String key,
final T value,
final Duration expiry);
/**
* Store a key value with a timeout expiry.
* @param key key
* @param value value
* @param expiry expiry
*/
void putWithTimeout(
final String key,
final T value,
final Duration expiry);
/**
* Get a String key value.
* @param confirmation confirmation
* @param key key
*/
void get( final Callback<Optional<T>> confirmation,
final String key);
/**
* Check to see if the store has the key
* @param hasKeyCallback hasKeyCallback
* @param key key
*/
void hasKey( final Callback<Boolean> hasKeyCallback,
final java.lang.String key);
/**
* Delete the key.
* @param key key
*/
void delete(final String key);
/**
* Delete the key with confirmation.
* @param key key
*/
void deleteWithConfirmation( final Callback<Boolean> confirmation,
final java.lang.String key);
void process();
}
Notice that the KeyValueStoreService
and LowLevelKeyValueStoreService
allow you to store and retrieve key/values. You can store keys/values that have an expiry.
-
StringDecoderEncoderKeyValueStore (implements
KeyValueStoreService<T>
) allows you to specify an encoder and decoder to convert objects to/fro Strings -
WriteBehindReadFallbackKeyValueStore (implements
LowLevelKeyValueStoreService
) allows you to specify two kvstores that will be both written to and read from in order. -
JsonKeyValueStoreServiceBuilder produces
StringDecoderEncoderKeyValueStore
that can serialize/parse object to/for Java/JSON. -
LowLevelLocalKeyValueStoreService (implements
LowLevelKeyValueStoreService
) is a near cache (in memory) for byte arrays and strings. -
RedisKeyValueStore (implements
LowLevelKeyValueStoreService
) is a cache that store key/value pairs in Redis. -
RedisKeyValueStoreBuilder produces
RedisKeyValueStore
instances.
You don't typically use the StringDecoderEncoderKeyValueStore
directly but you could. Instead you use it in conjunction with the JsonKeyValueStoreServiceBuilder
which constructs StringDecoderEncoderKeyValueStore
that do JSON encoding and decoding.
private JsonKeyValueStoreServiceBuilder jsonKeyValueStoreServiceBuilder;
private LowLevelLocalKeyValueStoreService localKeyValueStoreService = ...;
private KeyValueStoreService<Todo> keyValueStoreService;
jsonKeyValueStoreServiceBuilder.setLowLevelKeyValueStoreService(localKeyValueStoreService);
keyValueStoreService = jsonKeyValueStoreServiceBuilder.buildKeyValueStore(Todo.class);
keyValueStoreService.put("key", new Todo("value"));
Essentially JsonKeyValueStoreServiceBuilder
can turn a LowLevelLocalKeyValueStoreService
into a KeyValueStoreService<Todo>
(object store).
WriteBehindReadFallbackKeyValueStore
is used when you want to implement a write behind cache. If the local cache (or primary cache) gets a miss, then it will read from the remote cache (or secondary cache).
It is easy to decorate core low level back and back them by WriteBehindReadFallbackKeyValueStore
, and decorate encoding/decoding with JsonKeyValueStoreServiceBuilder
as follows:
Example using WriteBehindReadFallbackKeyValueStore and JsonKeyValueStoreServiceBuilder to decorate and wrap calls to RedisKeyValueStore and LowLevelLocalKeyValueStoreService
private RedisKeyValueStore keyValueStore;
private RedisKeyValueStoreBuilder builder;
final KeyValueStoreService<Todo> todoKVStoreInternal = JsonKeyValueStoreServiceBuilder
.jsonKeyValueStoreServiceBuilder()
.setLowLevelKeyValueStoreService(keyValueStore)
.buildKeyValueStore(Todo.class);
final KeyValueStoreService<Todo> todoKVStore = ServiceBuilder.serviceBuilder()
.setServiceObject(todoKVStoreInternal)
.buildAndStartAll()
.createProxyWithAutoFlush(KeyValueStoreService.class, Duration.FIFTY_MILLIS);
...
...
todoKVStore.putWithConfirmation(putCallbackBuilder.build(),
"testPutWithConfirmationWrapped",
new Todo(value));
todoKVStore.get(getCallbackBuilder.build(), "testPutWithConfirmationWrapped");
QBit Website What is Microservices Architecture?
QBit Java Micorservices lib tutorials
The Java microservice lib. QBit is a reactive programming lib for building microservices - JSON, HTTP, WebSocket, and REST. QBit uses reactive programming to build elastic REST, and WebSockets based cloud friendly, web services. SOA evolved for mobile and cloud. ServiceDiscovery, Health, reactive StatService, events, Java idiomatic reactive programming for Microservices.
Reactive Programming, Java Microservices, Rick Hightower
Java Microservices Architecture
[Microservice Service Discovery with Consul] (http://www.mammatustech.com/Microservice-Service-Discovery-with-Consul)
Microservices Service Discovery Tutorial with Consul
[Reactive Microservices] (http://www.mammatustech.com/reactive-microservices)
[High Speed Microservices] (http://www.mammatustech.com/high-speed-microservices)
Reactive Microservices Tutorial, using the Reactor
QBit is mentioned in the Restlet blog
All code is written using JetBrains Idea - the best IDE ever!
Kafka training, Kafka consulting, Cassandra training, Cassandra consulting, Spark training, Spark consulting
Tutorials
- QBit tutorials
- Microservices Intro
- Microservice KPI Monitoring
- Microservice Batteries Included
- RESTful APIs
- QBit and Reakt Promises
- Resourceful REST
- Microservices Reactor
- Working with JSON maps and lists
__
Docs
Getting Started
- First REST Microservice
- REST Microservice Part 2
- ServiceQueue
- ServiceBundle
- ServiceEndpointServer
- REST with URI Params
- Simple Single Page App
Basics
- What is QBit?
- Detailed Overview of QBit
- High level overview
- Low-level HTTP and WebSocket
- Low level WebSocket
- HttpClient
- HTTP Request filter
- HTTP Proxy
- Queues and flushing
- Local Proxies
- ServiceQueue remote and local
- ManagedServiceBuilder, consul, StatsD, Swagger support
- Working with Service Pools
- Callback Builders
- Error Handling
- Health System
- Stats System
- Reactor callback coordination
- Early Service Examples
Concepts
REST
Callbacks and Reactor
Event Bus
Advanced
Integration
- Using QBit in Vert.x
- Reactor-Integrating with Cassandra
- Using QBit with Spring Boot
- SolrJ and service pools
- Swagger support
- MDC Support
- Reactive Streams
- Mesos, Docker, Heroku
- DNS SRV
QBit case studies
QBit 2 Roadmap
-- Related Projects
- QBit Reactive Microservices
- Reakt Reactive Java
- Reakt Guava Bridge
- QBit Extensions
- Reactive Microservices
Kafka training, Kafka consulting, Cassandra training, Cassandra consulting, Spark training, Spark consulting