Skip to content

Commit c4f9d3f

Browse files
committed
Initial implementation of DTopic
OBP reimplemented Streams on top of TCP connections
1 parent 8650b65 commit c4f9d3f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

98 files changed

+6915
-2518
lines changed

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@
176176

177177
END OF TERMS AND CONDITIONS
178178

179-
Copyright 2018 Burak Sezer.
179+
Copyright 2018-2020 Burak Sezer.
180180

181181
Licensed under the Apache License, Version 2.0 (the "License");
182182
you may not use this file except in compliance with the License.

README.md

Lines changed: 97 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,13 @@ See [Docker](#docker) and [Sample Code](#sample-code) sections to get started!
2121
* Supports atomic operations,
2222
* Supports [distributed queries](#query) on keys,
2323
* Provides a plugin interface for service discovery daemons,
24-
* Provides a locking primitive which inspired by [SETNX of Redis](https://redis.io/commands/setnx#design-pattern-locking-with-codesetnxcode).
24+
* Provides a locking primitive which inspired by [SETNX of Redis](https://redis.io/commands/setnx#design-pattern-locking-with-codesetnxcode),
25+
* Supports [distributed topic](#distributed-topic) data structure,
2526

2627
## Possible Use Cases
2728

28-
With this feature set, Olric is suitable to use as a distributed cache. But it also provides data replication, failure detection
29-
and simple anti-entropy services. So it can be used as an ordinary key/value data store to scale your cloud application.
30-
31-
## Project Status
32-
33-
Olric is in early stages of development. The package API and client protocol may change without notification.
29+
With this feature set, Olric is suitable to use as a distributed cache. But it also provides distributed topics, data replication,
30+
failure detection and simple anti-entropy services. So it can be used as an ordinary key/value data store to scale your cloud application.
3431

3532
## Table of Contents
3633

@@ -49,28 +46,34 @@ Olric is in early stages of development. The package API and client protocol may
4946
* [olric-stats](#olric-stats)
5047
* [olric-load](#olric-load)
5148
* [Usage](#usage)
52-
* [Put](#put)
53-
* [PutIf](#putif)
54-
* [PutEx](#putex)
55-
* [PutIfEx](#putifex)
56-
* [Get](#get)
57-
* [Expire](#expire)
58-
* [Delete](#delete)
59-
* [LockWithTimeout](#lockwithtimeout)
60-
* [Lock](#lock)
61-
* [Unlock](#unlock)
62-
* [Destroy](#destroy)
63-
* [Stats](#stats)
64-
* [Ping](#ping)
65-
* [Query](#query)
66-
* [Cursor](#cursor)
67-
* [Range](#range)
68-
* [Close](#close)
69-
* [Atomic Operations](#atomic-operations)
70-
* [Incr](#incr)
71-
* [Decr](#decr)
72-
* [GetPut](#getput)
73-
* [Pipelining](#pipelining)
49+
* [Distributed Map](#distributed-map)
50+
* [Put](#put)
51+
* [PutIf](#putif)
52+
* [PutEx](#putex)
53+
* [PutIfEx](#putifex)
54+
* [Get](#get)
55+
* [Expire](#expire)
56+
* [Delete](#delete)
57+
* [LockWithTimeout](#lockwithtimeout)
58+
* [Lock](#lock)
59+
* [Unlock](#unlock)
60+
* [Destroy](#destroy)
61+
* [Stats](#stats)
62+
* [Ping](#ping)
63+
* [Query](#query)
64+
* [Cursor](#cursor)
65+
* [Range](#range)
66+
* [Close](#close)
67+
* [Atomic Operations](#atomic-operations)
68+
* [Incr](#incr)
69+
* [Decr](#decr)
70+
* [GetPut](#getput)
71+
* [Pipelining](#pipelining)
72+
* [Distributed Topic](#distributed-topic)
73+
* [Publish](#publish)
74+
* [AddListener](#addlistener)
75+
* [RemoveListener](#removelistener)
76+
* [Destroy](#destroy)
7477
* [Serialization](#serialization)
7578
* [Golang Client](#golang-client)
7679
* [Configuration](#configuration)
@@ -121,7 +124,8 @@ Olric is in early stages of development. The package API and client protocol may
121124
* Provides a plugin interface for service discovery daemons and cloud providers,
122125
* Provides a command-line-interface to access the cluster directly from the terminal,
123126
* Supports different serialization formats. Gob, JSON and MessagePack are supported out of the box,
124-
* Provides a locking primitive which inspired by [SETNX of Redis](https://redis.io/commands/setnx#design-pattern-locking-with-codesetnxcode).
127+
* Provides a locking primitive which inspired by [SETNX of Redis](https://redis.io/commands/setnx#design-pattern-locking-with-codesetnxcode),
128+
* Supports [distributed topic](#distributed-topic) data structure,
125129

126130
See [Architecture](#architecture) section to see details.
127131

@@ -130,7 +134,6 @@ See [Architecture](#architecture) section to see details.
130134
* Distributed queries over keys and values,
131135
* Database backend for persistence,
132136
* Anti-entropy system to repair inconsistencies in DMaps,
133-
* Publish/Subscribe for messaging,
134137
* Eviction listeners by using Publish/Subscribe,
135138
* Memcached interface,
136139
* Client implementations for different languages: Java, Python and JavaScript,
@@ -428,15 +431,6 @@ When you call **Start** method, your process joins the cluster and will be respo
428431
indefinitely. So you may need to run it in a goroutine. Of course, this is just a single-node instance, because you didn't give any
429432
configuration.
430433

431-
Create a **DMap** object to access the cluster:
432-
433-
```go
434-
dm, err := db.NewDMap("my-dmap")
435-
```
436-
437-
DMap object has *Put*, *PutEx*, *PutIf*, *PutIfEx*, *Get*, *Delete*, *Expire*, *LockWithTimeout* and *Destroy* methods to access
438-
and modify data in Olric. We may add more methods for finer control but first, I'm willing to stabilize this set of features.
439-
440434
When you want to leave the cluster, just need to call **Shutdown** method:
441435

442436
```go
@@ -447,6 +441,14 @@ This will stop background tasks and servers. Finally purges in-memory data and q
447441

448442
***Please note that this section aims to document DMap API in embedded member mode.*** If you prefer to use Olric in
449443
Client-Server mode, please jump to [Golang Client](#golang-client) section.
444+
445+
### Distributed Map
446+
447+
Create a **DMap** instance:
448+
449+
```go
450+
dm, err := db.NewDMap("my-dmap")
451+
```
450452

451453
### Put
452454

@@ -797,6 +799,61 @@ There is no hard-limit on message count in a pipeline. You should set a convenie
797799

798800
The `Flush` method returns errors along with success messages. Furthermore, you need to know the command order for matching responses with requests.
799801

802+
### Distributed Topic
803+
804+
Distributed topic is an asynchronous messaging service that decouples services that produce events from services that process events. It has two delivery modes:
805+
806+
* **olric.UnorderedDelivery**: Messages are delivered in random order. It's good to distribute independent events in a distributed system.
807+
* **olric.OrderedDelivery**: Messages are delivered in some order. Not implemented yet.
808+
809+
You should know that:
810+
811+
* Communication between parties is one-to-many (fan-out).
812+
* All data is in-memory, and the published messages are not stored in the cluster.
813+
* Fire&Forget: message delivery is not guaranteed.
814+
815+
Create a **DTopic** instance:
816+
817+
```go
818+
dt, err := db.NewDTopic("my-topic", 0, olric.UnorderedDelivery)
819+
```
820+
821+
### Publish
822+
823+
Publish sends a message to the given topic. It accepts any serializable type as message.
824+
825+
```go
826+
err := dt.Publish("my-message")
827+
```
828+
829+
### AddListener
830+
831+
AddListener adds a new listener for the topic. Returns a listener ID or a non-nil error. The callback functions for this DTopic are run by parallel.
832+
833+
```go
834+
listenerID, err := dt.AddListener(func(msg DTopicMessage) {
835+
fmt.Println("Message:", msg)
836+
})
837+
```
838+
839+
You have to store `listenerID` to remove the listener.
840+
841+
### RemoveListener
842+
843+
RemoveListener removes a listener with the given listenerID.
844+
845+
```go
846+
err := dt.RemoveListener(listenerID)
847+
```
848+
849+
### Destroy
850+
851+
Destroy a DTopic from the cluster. It stops background goroutines and releases underlying data structures.
852+
853+
```go
854+
err := dt.Destroy()
855+
```
856+
800857
## Golang Client
801858

802859
This repo contains the official Golang client for Olric. It implements Olric Binary Protocol(OBP). With this client,

cache.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import (
2222
"github.com/buraksezer/olric/config"
2323
)
2424

25-
// cache keeps cache control parameters and access-log for keys in a DMap.
25+
// cache keeps cache control parameters and access-log for keys in a dmap.
2626
type cache struct {
2727
sync.RWMutex // protects accessLog
2828

@@ -36,7 +36,7 @@ type cache struct {
3636
}
3737

3838
func (db *Olric) setCacheConfiguration(dm *dmap, name string) error {
39-
// Try to set cache configuration for this DMap.
39+
// Try to set cache configuration for this dmap.
4040
dm.cache = &cache{}
4141
dm.cache.maxIdleDuration = db.config.Cache.MaxIdleDuration
4242
dm.cache.ttlDuration = db.config.Cache.TTLDuration

client/README.md

Lines changed: 92 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,35 @@ This implementation also supports connection pooling by default.
88
## Table of Contents
99

1010
* [Setup](#setup)
11-
* [Commands](#commands)
12-
* [Put](#put)
13-
* [PutIf](#putif)
14-
* [PutEx](#putex)
15-
* [PutIfEx](#putifex)
16-
* [Get](#get)
17-
* [Expire](#expire)
18-
* [Delete](#delete)
19-
* [LockWithTimeout](#lockwithtimeout)
20-
* [Lock](#lock)
21-
* [Unlock](#unlock)
22-
* [Destroy](#destroy)
23-
* [Stats](#stats)
24-
* [Ping](#ping)
25-
* [Query](#query)
26-
* [Cursor](#cursor)
27-
* [Range](#range)
28-
* [Close](#close)
29-
* [Atomic Operations](#atomic-operations)
30-
* [Incr](#incr)
31-
* [Decr](#decr)
32-
* [GetPut](#getput)
33-
* [Pipelining](#pipelining)
11+
* [Data Structures](#data-structures)
12+
* [Distributed Map](#distributed-topic)
13+
* [Put](#put)
14+
* [PutIf](#putif)
15+
* [PutEx](#putex)
16+
* [PutIfEx](#putifex)
17+
* [Get](#get)
18+
* [Expire](#expire)
19+
* [Delete](#delete)
20+
* [LockWithTimeout](#lockwithtimeout)
21+
* [Lock](#lock)
22+
* [Unlock](#unlock)
23+
* [Destroy](#destroy)
24+
* [Stats](#stats)
25+
* [Ping](#ping)
26+
* [Query](#query)
27+
* [Cursor](#cursor)
28+
* [Range](#range)
29+
* [Close](#close)
30+
* [Atomic Operations](#atomic-operations)
31+
* [Incr](#incr)
32+
* [Decr](#decr)
33+
* [GetPut](#getput)
34+
* [Pipelining](#pipelining)
35+
* [Distributed Topic](#distributed-topic)
36+
* [Publish](#publish)
37+
* [AddListener](#addlistener)
38+
* [RemoveListener](#removelistener)
39+
* [Destroy](#destroy)
3440
* [Serialization](#serialization)
3541
* [Sample Code](#sample-code)
3642

@@ -60,7 +66,14 @@ c, err := client.New(clientConfig)
6066
A client (it's `c` in our sample) instance should be created one time in your program's life time. See [Sample Code](#sample-code) section
6167
to see it in action.
6268

63-
## Commands
69+
## Data Structures
70+
71+
Olric currently provides two different data structures:
72+
73+
* [Distributed Map](#distributed-map)
74+
* [Distributed Topic](#distributed-topic)
75+
76+
## Distributed Map
6477

6578
Before starting, you need to create a new DMap instance:
6679

@@ -360,6 +373,61 @@ value, err := dm.GetPut("atomic-key", someType{})
360373

361374
The returned value is an arbitrary type.
362375

376+
## Distributed Topic
377+
378+
Distributed topic is an asynchronous messaging service that decouples services that produce events from services that process events. It has two delivery modes:
379+
380+
* **olric.UnorderedDelivery**: Messages are delivered in random order. It's good to distribute independent events in a distributed system.
381+
* **olric.OrderedDelivery**: Messages are delivered in some order. Not implemented yet.
382+
383+
You should know that:
384+
385+
* Communication between parties is one-to-many (fan-out).
386+
* All data is in-memory, and the published messages are not stored in the cluster.
387+
* Fire&Forget: message delivery is not guaranteed.
388+
389+
Create a **DTopic** instance:
390+
391+
```go
392+
dt, err := db.NewDTopic("my-topic", 0, olric.UnorderedDelivery)
393+
```
394+
395+
### Publish
396+
397+
Publish sends a message to the given topic. It accepts any serializable type as message.
398+
399+
```go
400+
err := dt.Publish("my-message")
401+
```
402+
403+
### AddListener
404+
405+
AddListener adds a new listener for the topic. Returns a listener ID or a non-nil error. The callback functions for this DTopic are run by parallel.
406+
407+
```go
408+
listenerID, err := dt.AddListener(func(msg DTopicMessage) {
409+
fmt.Println("Message:", msg)
410+
})
411+
```
412+
413+
You have to store `listenerID` to remove the listener.
414+
415+
### RemoveListener
416+
417+
RemoveListener removes a listener with the given listenerID.
418+
419+
```go
420+
err := dt.RemoveListener(listenerID)
421+
```
422+
423+
### Destroy
424+
425+
Destroy a DTopic from the cluster. It stops background goroutines and releases underlying data structures.
426+
427+
```go
428+
err := dt.Destroy()
429+
```
430+
363431
## Serialization
364432

365433
All data in an Olric cluster has to be serialized into byte form before transferring or storing. You can freely choice

0 commit comments

Comments
 (0)