Skip to content

Commit 9a7dbef

Browse files
authored
feat: add in-memory sequencer (#398)
1 parent 13f5154 commit 9a7dbef

File tree

8 files changed

+227
-0
lines changed

8 files changed

+227
-0
lines changed

cmd/layotto/main.go

+4
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ import (
115115

116116
// Sequencer
117117
sequencer_etcd "mosn.io/layotto/components/sequencer/etcd"
118+
sequencer_inmemory "mosn.io/layotto/components/sequencer/in-memory"
118119
sequencer_mongo "mosn.io/layotto/components/sequencer/mongo"
119120
sequencer_redis "mosn.io/layotto/components/sequencer/redis"
120121
sequencer_zookeeper "mosn.io/layotto/components/sequencer/zookeeper"
@@ -375,6 +376,9 @@ func NewRuntimeGrpcServer(data json.RawMessage, opts ...grpc.ServerOption) (mgrp
375376
runtime_sequencer.NewFactory("mongo", func() sequencer.Store {
376377
return sequencer_mongo.NewMongoSequencer(log.DefaultLogger)
377378
}),
379+
runtime_sequencer.NewFactory("in-memory", func() sequencer.Store {
380+
return sequencer_inmemory.NewInMemorySequencer()
381+
}),
378382
),
379383
// secretstores
380384
runtime.WithSecretStoresFactory(

cmd/layotto_multiple_api/main.go

+4
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ import (
108108

109109
// Sequencer
110110
sequencer_etcd "mosn.io/layotto/components/sequencer/etcd"
111+
sequencer_inmemory "mosn.io/layotto/components/sequencer/in-memory"
111112
sequencer_redis "mosn.io/layotto/components/sequencer/redis"
112113
sequencer_zookeeper "mosn.io/layotto/components/sequencer/zookeeper"
113114

@@ -366,6 +367,9 @@ func NewRuntimeGrpcServer(data json.RawMessage, opts ...grpc.ServerOption) (mgrp
366367
runtime_sequencer.NewFactory("zookeeper", func() sequencer.Store {
367368
return sequencer_zookeeper.NewZookeeperSequencer(log.DefaultLogger)
368369
}),
370+
runtime_sequencer.NewFactory("in-memory", func() sequencer.Store {
371+
return sequencer_inmemory.NewInMemorySequencer()
372+
}),
369373
))
370374
return server, err
371375
}

components/go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ require (
3232
go.etcd.io/etcd/client/v3 v3.5.0
3333
go.etcd.io/etcd/server/v3 v3.5.0
3434
go.mongodb.org/mongo-driver v1.8.0
35+
go.uber.org/atomic v1.7.0
3536
golang.org/x/net v0.0.0-20210614182718-04defd469f4e // indirect
3637
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5 // indirect
3738
google.golang.org/grpc v1.38.0
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright 2021 Layotto Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package in_memory
18+
19+
import (
20+
"go.uber.org/atomic"
21+
"mosn.io/layotto/components/sequencer"
22+
"sync"
23+
)
24+
25+
type InMemorySequencer struct {
26+
data *sync.Map
27+
}
28+
29+
func NewInMemorySequencer() *InMemorySequencer {
30+
return &InMemorySequencer{
31+
data: &sync.Map{},
32+
}
33+
}
34+
35+
func (s *InMemorySequencer) Init(_ sequencer.Configuration) error {
36+
return nil
37+
}
38+
39+
func (s *InMemorySequencer) GetNextId(req *sequencer.GetNextIdRequest) (*sequencer.GetNextIdResponse, error) {
40+
seed, ok := s.data.Load(req.Key)
41+
if !ok {
42+
seed, _ = s.data.LoadOrStore(req.Key, &atomic.Int64{})
43+
}
44+
45+
nextId := seed.(*atomic.Int64).Inc()
46+
return &sequencer.GetNextIdResponse{NextId: nextId}, nil
47+
48+
}
49+
50+
func (s *InMemorySequencer) GetSegment(req *sequencer.GetSegmentRequest) (bool, *sequencer.GetSegmentResponse, error) {
51+
seed, ok := s.data.Load(req.Key)
52+
if !ok {
53+
seed, _ = s.data.LoadOrStore(req.Key, &atomic.Int64{})
54+
}
55+
56+
res := seed.(*atomic.Int64).Add(int64(req.Size))
57+
return true, &sequencer.GetSegmentResponse{
58+
From: res - int64(req.Size) + 1,
59+
To: res,
60+
}, nil
61+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
* Copyright 2021 Layotto Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package in_memory
18+
19+
import (
20+
"testing"
21+
22+
"github.com/stretchr/testify/assert"
23+
24+
"mosn.io/layotto/components/sequencer"
25+
)
26+
27+
func TestNew(t *testing.T) {
28+
s := NewInMemorySequencer()
29+
30+
assert.NotNil(t, s)
31+
}
32+
33+
func TestInit(t *testing.T) {
34+
s := NewInMemorySequencer()
35+
assert.NotNil(t, s)
36+
37+
err := s.Init(sequencer.Configuration{})
38+
assert.NoError(t, err)
39+
}
40+
41+
func TestGetNextId(t *testing.T) {
42+
s := NewInMemorySequencer()
43+
assert.NotNil(t, s)
44+
45+
err := s.Init(sequencer.Configuration{})
46+
assert.NoError(t, err)
47+
48+
var resp *sequencer.GetNextIdResponse
49+
resp, err = s.GetNextId(&sequencer.GetNextIdRequest{Key: "666"})
50+
assert.NoError(t, err)
51+
assert.Equal(t, int64(1), resp.NextId)
52+
53+
resp, err = s.GetNextId(&sequencer.GetNextIdRequest{Key: "666"})
54+
assert.NoError(t, err)
55+
assert.Equal(t, int64(2), resp.NextId)
56+
57+
resp, err = s.GetNextId(&sequencer.GetNextIdRequest{Key: "777"})
58+
assert.NoError(t, err)
59+
assert.Equal(t, int64(1), resp.NextId)
60+
}
61+
62+
func TestGetSegment(t *testing.T) {
63+
s := NewInMemorySequencer()
64+
assert.NotNil(t, s)
65+
66+
err := s.Init(sequencer.Configuration{})
67+
assert.NoError(t, err)
68+
69+
var resp *sequencer.GetSegmentResponse
70+
var res bool
71+
res, resp, err = s.GetSegment(&sequencer.GetSegmentRequest{Key: "666", Size: 5})
72+
assert.NoError(t, err)
73+
assert.Equal(t, int64(1), resp.From)
74+
assert.Equal(t, int64(5), resp.To)
75+
assert.True(t, res)
76+
77+
res, resp, err = s.GetSegment(&sequencer.GetSegmentRequest{Key: "666", Size: 5})
78+
assert.NoError(t, err)
79+
assert.Equal(t, int64(6), resp.From)
80+
assert.Equal(t, int64(10), resp.To)
81+
assert.True(t, res)
82+
83+
res, resp, err = s.GetSegment(&sequencer.GetSegmentRequest{Key: "777", Size: 5})
84+
assert.NoError(t, err)
85+
assert.Equal(t, int64(1), resp.From)
86+
assert.Equal(t, int64(5), resp.To)
87+
assert.True(t, res)
88+
89+
}

configs/config_in_memory.json

+5
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@
3939
}
4040
}
4141
},
42+
"sequencer": {
43+
"in-memory": {
44+
"metadata": {}
45+
}
46+
},
4247
"app": {
4348
"app_id": "app1",
4449
"grpc_callback_port": 9999

demo/sequencer/in-memory/client.go

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"fmt"
6+
client "mosn.io/layotto/sdk/go-sdk/client"
7+
runtimev1pb "mosn.io/layotto/spec/proto/runtime/v1"
8+
)
9+
10+
const (
11+
key = "key666"
12+
storeName = "in-memory"
13+
)
14+
15+
func main() {
16+
17+
cli, err := client.NewClient()
18+
if err != nil {
19+
panic(err)
20+
}
21+
defer cli.Close()
22+
ctx := context.Background()
23+
fmt.Printf("Try to get next id.Key:%s \n", key)
24+
for i := 0; i < 10; i++ {
25+
id, err := cli.GetNextId(ctx, &runtimev1pb.GetNextIdRequest{
26+
StoreName: storeName,
27+
Key: key,
28+
Options: nil,
29+
Metadata: nil,
30+
})
31+
if err != nil {
32+
fmt.Print(err)
33+
return
34+
}
35+
fmt.Printf("Next id:%v \n", id)
36+
}
37+
fmt.Println("Demo success!")
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# In-Memory
2+
3+
## 配置项说明
4+
5+
直接使用配置:configs/config_in_memory.json
6+
7+
8+
## 启动 layotto
9+
10+
````shell
11+
cd ${projectpath}/cmd/layotto
12+
go build
13+
````
14+
编译成功后执行:
15+
````shell
16+
./layotto start -c ../../configs/config_in_memory.json
17+
````
18+
19+
## 运行 Demo
20+
21+
````shell
22+
cd ${projectpath}/demo/sequencer/in-memory/
23+
go build -o client
24+
./client
25+
````

0 commit comments

Comments
 (0)