diff --git a/cmd/layotto/main.go b/cmd/layotto/main.go index 1394e6bb34..e2455f638a 100644 --- a/cmd/layotto/main.go +++ b/cmd/layotto/main.go @@ -108,6 +108,7 @@ import ( "mosn.io/layotto/components/lock" lock_consul "mosn.io/layotto/components/lock/consul" lock_etcd "mosn.io/layotto/components/lock/etcd" + lock_inmemory "mosn.io/layotto/components/lock/in-memory" lock_mongo "mosn.io/layotto/components/lock/mongo" lock_redis "mosn.io/layotto/components/lock/redis" lock_zookeeper "mosn.io/layotto/components/lock/zookeeper" @@ -115,6 +116,7 @@ import ( // Sequencer sequencer_etcd "mosn.io/layotto/components/sequencer/etcd" + sequencer_inmemory "mosn.io/layotto/components/sequencer/in-memory" sequencer_mongo "mosn.io/layotto/components/sequencer/mongo" sequencer_redis "mosn.io/layotto/components/sequencer/redis" sequencer_zookeeper "mosn.io/layotto/components/sequencer/zookeeper" @@ -352,6 +354,9 @@ func NewRuntimeGrpcServer(data json.RawMessage, opts ...grpc.ServerOption) (mgrp runtime_lock.NewFactory("mongo", func() lock.LockStore { return lock_mongo.NewMongoLock(log.DefaultLogger) }), + runtime_lock.NewFactory("in-memory", func() lock.LockStore { + return lock_inmemory.NewInMemoryLock() + }), ), // bindings @@ -375,6 +380,9 @@ func NewRuntimeGrpcServer(data json.RawMessage, opts ...grpc.ServerOption) (mgrp runtime_sequencer.NewFactory("mongo", func() sequencer.Store { return sequencer_mongo.NewMongoSequencer(log.DefaultLogger) }), + runtime_sequencer.NewFactory("in-memory", func() sequencer.Store { + return sequencer_inmemory.NewInMemorySequencer() + }), ), // secretstores runtime.WithSecretStoresFactory( diff --git a/cmd/layotto_multiple_api/main.go b/cmd/layotto_multiple_api/main.go index d037702df7..01d9872d45 100644 --- a/cmd/layotto_multiple_api/main.go +++ b/cmd/layotto_multiple_api/main.go @@ -102,12 +102,14 @@ import ( "mosn.io/layotto/components/lock" lock_consul "mosn.io/layotto/components/lock/consul" lock_etcd "mosn.io/layotto/components/lock/etcd" + lock_inmemory "mosn.io/layotto/components/lock/in-memory" lock_redis "mosn.io/layotto/components/lock/redis" lock_zookeeper "mosn.io/layotto/components/lock/zookeeper" runtime_lock "mosn.io/layotto/pkg/runtime/lock" // Sequencer sequencer_etcd "mosn.io/layotto/components/sequencer/etcd" + sequencer_inmemory "mosn.io/layotto/components/sequencer/in-memory" sequencer_redis "mosn.io/layotto/components/sequencer/redis" sequencer_zookeeper "mosn.io/layotto/components/sequencer/zookeeper" @@ -346,6 +348,9 @@ func NewRuntimeGrpcServer(data json.RawMessage, opts ...grpc.ServerOption) (mgrp runtime_lock.NewFactory("consul", func() lock.LockStore { return lock_consul.NewConsulLock(log.DefaultLogger) }), + runtime_lock.NewFactory("in-memory", func() lock.LockStore { + return lock_inmemory.NewInMemoryLock() + }), ), // bindings @@ -366,6 +371,9 @@ func NewRuntimeGrpcServer(data json.RawMessage, opts ...grpc.ServerOption) (mgrp runtime_sequencer.NewFactory("zookeeper", func() sequencer.Store { return sequencer_zookeeper.NewZookeeperSequencer(log.DefaultLogger) }), + runtime_sequencer.NewFactory("in-memory", func() sequencer.Store { + return sequencer_inmemory.NewInMemorySequencer() + }), )) return server, err } diff --git a/components/go.mod b/components/go.mod index 145658feb4..4d52b353d1 100644 --- a/components/go.mod +++ b/components/go.mod @@ -32,6 +32,7 @@ require ( go.etcd.io/etcd/client/v3 v3.5.0 go.etcd.io/etcd/server/v3 v3.5.0 go.mongodb.org/mongo-driver v1.8.0 + go.uber.org/atomic v1.7.0 golang.org/x/net v0.0.0-20210614182718-04defd469f4e // indirect golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5 // indirect google.golang.org/grpc v1.38.0 diff --git a/components/lock/in-memory/in_memory_lock.go b/components/lock/in-memory/in_memory_lock.go new file mode 100644 index 0000000000..deaf4c4e18 --- /dev/null +++ b/components/lock/in-memory/in_memory_lock.go @@ -0,0 +1,132 @@ +/* + * Copyright 2021 Layotto Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package in_memory + +import ( + "mosn.io/layotto/components/lock" + "sync" + "time" +) + +type InMemoryLock struct { + features []lock.Feature + data *lockMap +} + +// memoryLock is a lock holder +type memoryLock struct { + key string + owner string + expireTime time.Time + lock int +} + +type lockMap struct { + sync.Mutex + locks map[string]*memoryLock +} + +func NewInMemoryLock() *InMemoryLock { + return &InMemoryLock{ + features: make([]lock.Feature, 0), + data: &lockMap{ + locks: make(map[string]*memoryLock), + }, + } +} + +func (s *InMemoryLock) Init(_ lock.Metadata) error { + return nil +} + +func (s *InMemoryLock) Features() []lock.Feature { + return s.features +} + +// Try to add a lock. Currently this is a non-reentrant lock +func (s *InMemoryLock) TryLock(req *lock.TryLockRequest) (*lock.TryLockResponse, error) { + s.data.Lock() + defer s.data.Unlock() + // 1. Find the memoryLock for this resourceId + item, ok := s.data.locks[req.ResourceId] + if !ok { + item = &memoryLock{ + key: req.ResourceId, + //0 unlock, 1 lock + lock: 0, + } + s.data.locks[req.ResourceId] = item + } + + // 2. Construct a new one if the lockData has expired + //check expire + if item.owner != "" && time.Now().After(item.expireTime) { + item = &memoryLock{ + key: req.ResourceId, + lock: 0, + } + s.data.locks[req.ResourceId] = item + } + + // 3. Check if it has been locked by others. + // Currently this is a non-reentrant lock + if item.lock == 1 { + //lock failed + return &lock.TryLockResponse{ + Success: false, + }, nil + } + + // 4. Update owner information + item.lock = 1 + item.owner = req.LockOwner + item.expireTime = time.Now().Add(time.Second * time.Duration(req.Expire)) + + return &lock.TryLockResponse{ + Success: true, + }, nil +} + +func (s *InMemoryLock) Unlock(req *lock.UnlockRequest) (*lock.UnlockResponse, error) { + s.data.Lock() + defer s.data.Unlock() + // 1. Find the memoryLock for this resourceId + item, ok := s.data.locks[req.ResourceId] + + if !ok { + return &lock.UnlockResponse{ + Status: lock.LOCK_UNEXIST, + }, nil + } + // 2. check the owner information + if item.lock != 1 { + return &lock.UnlockResponse{ + Status: lock.LOCK_UNEXIST, + }, nil + } + if item.owner != req.LockOwner { + return &lock.UnlockResponse{ + Status: lock.LOCK_BELONG_TO_OTHERS, + }, nil + } + // 3. unlock and reset the owner information + item.owner = "" + item.lock = 0 + return &lock.UnlockResponse{ + Status: lock.SUCCESS, + }, nil +} diff --git a/components/lock/in-memory/in_memory_lock_test.go b/components/lock/in-memory/in_memory_lock_test.go new file mode 100644 index 0000000000..4843b84bf8 --- /dev/null +++ b/components/lock/in-memory/in_memory_lock_test.go @@ -0,0 +1,165 @@ +/* + * Copyright 2021 Layotto Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package in_memory + +import ( + "github.com/stretchr/testify/assert" + "mosn.io/layotto/components/lock" + "testing" + "time" +) + +func TestNew(t *testing.T) { + s := NewInMemoryLock() + assert.NotNil(t, s) +} + +func TestInit(t *testing.T) { + s := NewInMemoryLock() + assert.NotNil(t, s) + + err := s.Init(lock.Metadata{}) + assert.NoError(t, err) +} + +func TestFeatures(t *testing.T) { + s := NewInMemoryLock() + assert.NotNil(t, s) + + f := s.Features() + assert.NotNil(t, f) + assert.Equal(t, 0, len(f)) +} + +func TestTryLock(t *testing.T) { + s := NewInMemoryLock() + assert.NotNil(t, s) + + req := &lock.TryLockRequest{ + ResourceId: "key111", + LockOwner: "own", + Expire: 3, + } + + var err error + var resp *lock.TryLockResponse + resp, err = s.TryLock(req) + assert.NoError(t, err) + assert.NotNil(t, req) + assert.True(t, resp.Success) + + resp, err = s.TryLock(req) + assert.NoError(t, err) + assert.NotNil(t, req) + assert.False(t, resp.Success) + + req = &lock.TryLockRequest{ + ResourceId: "key112", + LockOwner: "own", + Expire: 1, + } + + resp, err = s.TryLock(req) + assert.NoError(t, err) + assert.NotNil(t, req) + assert.True(t, resp.Success) + + req = &lock.TryLockRequest{ + ResourceId: "key112", + LockOwner: "own", + Expire: 1, + } + + resp, err = s.TryLock(req) + assert.NoError(t, err) + assert.NotNil(t, req) + assert.False(t, resp.Success) + + s.data.locks["key112"].expireTime = time.Now().Add(-2 * time.Second) + + resp, err = s.TryLock(req) + assert.NoError(t, err) + assert.NotNil(t, req) + assert.True(t, resp.Success) + +} + +func TestUnLock(t *testing.T) { + s := NewInMemoryLock() + assert.NotNil(t, s) + + req := &lock.UnlockRequest{ + ResourceId: "key111", + LockOwner: "own", + } + + var err error + var resp *lock.UnlockResponse + resp, err = s.Unlock(req) + assert.NoError(t, err) + assert.NotNil(t, req) + assert.Equal(t, lock.LOCK_UNEXIST, resp.Status) + + lockReq := &lock.TryLockRequest{ + ResourceId: "key111", + LockOwner: "own", + Expire: 10, + } + + var lockResp *lock.TryLockResponse + lockResp, err = s.TryLock(lockReq) + assert.NoError(t, err) + assert.NotNil(t, req) + assert.True(t, lockResp.Success) + + resp, err = s.Unlock(req) + assert.NoError(t, err) + assert.NotNil(t, req) + assert.Equal(t, lock.SUCCESS, resp.Status) + + lockResp, err = s.TryLock(lockReq) + assert.NoError(t, err) + assert.NotNil(t, req) + assert.True(t, lockResp.Success) + + req.LockOwner = "1" + + resp, err = s.Unlock(req) + assert.NoError(t, err) + assert.NotNil(t, req) + assert.Equal(t, lock.LOCK_BELONG_TO_OTHERS, resp.Status) + + req.ResourceId = "11" + lockReq.ResourceId = "11" + req.LockOwner = "own1" + lockReq.LockOwner = "own1" + lockResp, err = s.TryLock(lockReq) + assert.NoError(t, err) + assert.NotNil(t, req) + assert.True(t, lockResp.Success) + + resp, err = s.Unlock(req) + assert.NoError(t, err) + assert.NotNil(t, req) + assert.Equal(t, lock.SUCCESS, resp.Status) + + resp, err = s.Unlock(req) + assert.NoError(t, err) + assert.NotNil(t, req) + assert.Equal(t, lock.LOCK_UNEXIST, resp.Status) + +} diff --git a/components/sequencer/in-memory/in_memory_sequencer.go b/components/sequencer/in-memory/in_memory_sequencer.go new file mode 100644 index 0000000000..0883e92268 --- /dev/null +++ b/components/sequencer/in-memory/in_memory_sequencer.go @@ -0,0 +1,61 @@ +/* + * Copyright 2021 Layotto Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package in_memory + +import ( + "go.uber.org/atomic" + "mosn.io/layotto/components/sequencer" + "sync" +) + +type InMemorySequencer struct { + data *sync.Map +} + +func NewInMemorySequencer() *InMemorySequencer { + return &InMemorySequencer{ + data: &sync.Map{}, + } +} + +func (s *InMemorySequencer) Init(_ sequencer.Configuration) error { + return nil +} + +func (s *InMemorySequencer) GetNextId(req *sequencer.GetNextIdRequest) (*sequencer.GetNextIdResponse, error) { + seed, ok := s.data.Load(req.Key) + if !ok { + seed, _ = s.data.LoadOrStore(req.Key, &atomic.Int64{}) + } + + nextId := seed.(*atomic.Int64).Inc() + return &sequencer.GetNextIdResponse{NextId: nextId}, nil + +} + +func (s *InMemorySequencer) GetSegment(req *sequencer.GetSegmentRequest) (bool, *sequencer.GetSegmentResponse, error) { + seed, ok := s.data.Load(req.Key) + if !ok { + seed, _ = s.data.LoadOrStore(req.Key, &atomic.Int64{}) + } + + res := seed.(*atomic.Int64).Add(int64(req.Size)) + return true, &sequencer.GetSegmentResponse{ + From: res - int64(req.Size) + 1, + To: res, + }, nil +} diff --git a/components/sequencer/in-memory/in_memory_sequencer_test.go b/components/sequencer/in-memory/in_memory_sequencer_test.go new file mode 100644 index 0000000000..dc62b7dd35 --- /dev/null +++ b/components/sequencer/in-memory/in_memory_sequencer_test.go @@ -0,0 +1,89 @@ +/* + * Copyright 2021 Layotto Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package in_memory + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "mosn.io/layotto/components/sequencer" +) + +func TestNew(t *testing.T) { + s := NewInMemorySequencer() + + assert.NotNil(t, s) +} + +func TestInit(t *testing.T) { + s := NewInMemorySequencer() + assert.NotNil(t, s) + + err := s.Init(sequencer.Configuration{}) + assert.NoError(t, err) +} + +func TestGetNextId(t *testing.T) { + s := NewInMemorySequencer() + assert.NotNil(t, s) + + err := s.Init(sequencer.Configuration{}) + assert.NoError(t, err) + + var resp *sequencer.GetNextIdResponse + resp, err = s.GetNextId(&sequencer.GetNextIdRequest{Key: "666"}) + assert.NoError(t, err) + assert.Equal(t, int64(1), resp.NextId) + + resp, err = s.GetNextId(&sequencer.GetNextIdRequest{Key: "666"}) + assert.NoError(t, err) + assert.Equal(t, int64(2), resp.NextId) + + resp, err = s.GetNextId(&sequencer.GetNextIdRequest{Key: "777"}) + assert.NoError(t, err) + assert.Equal(t, int64(1), resp.NextId) +} + +func TestGetSegment(t *testing.T) { + s := NewInMemorySequencer() + assert.NotNil(t, s) + + err := s.Init(sequencer.Configuration{}) + assert.NoError(t, err) + + var resp *sequencer.GetSegmentResponse + var res bool + res, resp, err = s.GetSegment(&sequencer.GetSegmentRequest{Key: "666", Size: 5}) + assert.NoError(t, err) + assert.Equal(t, int64(1), resp.From) + assert.Equal(t, int64(5), resp.To) + assert.True(t, res) + + res, resp, err = s.GetSegment(&sequencer.GetSegmentRequest{Key: "666", Size: 5}) + assert.NoError(t, err) + assert.Equal(t, int64(6), resp.From) + assert.Equal(t, int64(10), resp.To) + assert.True(t, res) + + res, resp, err = s.GetSegment(&sequencer.GetSegmentRequest{Key: "777", Size: 5}) + assert.NoError(t, err) + assert.Equal(t, int64(1), resp.From) + assert.Equal(t, int64(5), resp.To) + assert.True(t, res) + +} diff --git a/configs/config_apollo_health_mq.json b/configs/config_apollo_health_mq.json deleted file mode 100644 index 1604c7d642..0000000000 --- a/configs/config_apollo_health_mq.json +++ /dev/null @@ -1,104 +0,0 @@ -{ - "servers": [ - { - "default_log_path": "stdout", - "default_log_level": "DEBUG", - "routers": [ - { - "router_config_name": "actuator_dont_need_router" - } - ], - "listeners": [ - { - "name": "grpc", - "address": "127.0.0.1:34904", - "bind_port": true, - "filter_chains": [ - { - "filters": [ - { - "type": "tcpcopy", - "config": { - "strategy": { - "switch": "ON", - "interval": 30, - "duration": 10, - "cpu_max_rate": 80, - "mem_max_rate": 80 - } - } - }, - { - "type": "grpc", - "config": { - "server_name": "runtime", - "grpc_config": { - "hellos": { - "helloworld": { - "hello": "greeting" - } - }, - "config_store": { - "apollo": { - "address": [ - "http://106.54.227.205:8080" - ], - "metadata": { - "app_id": "testApplication_yang", - "cluster": "default", - "namespace_name": "dubbo,product.joe,application", - "is_backup_config": "true", - "secret": "6ce3ff7e96a24335a9634fe9abca6d51", - "open_api_token": "947b0db097d2931ba5bf503f1e33c10394f90d11", - "open_api_address": "http://106.54.227.205", - "open_api_user": "apollo" - } - } - }, - "pub_subs": { - "redis": { - "metadata": { - "redisHost": "localhost:6380", - "redisPassword": "" - } - } - }, - "app": { - "app_id": "test111", - "grpc_callback_port": 9999 - } - } - } - } - ] - } - ] - }, - { - "name": "actuator", - "address": "127.0.0.1:34999", - "bind_port": true, - "filter_chains": [ - { - "filters": [ - { - "type": "proxy", - "config": { - "downstream_protocol": "Http1", - "upstream_protocol": "Http1", - "router_config_name": "actuator_dont_need_router" - } - } - ] - } - ], - "stream_filters": [ - { - "type": "actuator_filter" - } - ] - } - ] - } - ] -} diff --git a/configs/config_in_memory.json b/configs/config_in_memory.json index d1a01c7a74..32c8ef30c2 100644 --- a/configs/config_in_memory.json +++ b/configs/config_in_memory.json @@ -32,6 +32,12 @@ } } }, + "lock": { + "in-memory": { + "metadata": { + } + } + }, "pub_subs": { "in-memory": { "metadata": { @@ -39,6 +45,11 @@ } } }, + "sequencer": { + "in-memory": { + "metadata": {} + } + }, "app": { "app_id": "app1", "grpc_callback_port": 9999 diff --git a/demo/lock/in-memory/client.go b/demo/lock/in-memory/client.go new file mode 100644 index 0000000000..0d9daebd75 --- /dev/null +++ b/demo/lock/in-memory/client.go @@ -0,0 +1,108 @@ +package main + +import ( + "context" + "fmt" + "github.com/google/uuid" + client "mosn.io/layotto/sdk/go-sdk/client" + runtimev1pb "mosn.io/layotto/spec/proto/runtime/v1" + "sync" +) + +const ( + resourceId = "resource_a" + storeName = "in-memory" +) + +func main() { + cli, err := client.NewClient() + if err != nil { + panic(err) + } + defer cli.Close() + ctx := context.Background() + // 1. Client trylock + owner1 := uuid.New().String() + fmt.Println("client1 prepare to tryLock...") + resp, err := cli.TryLock(ctx, &runtimev1pb.TryLockRequest{ + StoreName: storeName, + ResourceId: resourceId, + LockOwner: owner1, + Expire: 1000, + }) + if err != nil { + panic(err) + } + if !resp.Success { + panic("TryLock failed") + } + fmt.Printf("client1 got lock!ResourceId is %s\n", resourceId) + var wg sync.WaitGroup + wg.Add(1) + // 2. Client2 tryLock fail + go func() { + fmt.Println("client2 prepare to tryLock...") + owner2 := uuid.New().String() + resp, err := cli.TryLock(ctx, &runtimev1pb.TryLockRequest{ + StoreName: storeName, + ResourceId: resourceId, + LockOwner: owner2, + Expire: 10, + }) + if err != nil { + panic(err) + } + if resp.Success { + panic("client2 got lock?!") + } + fmt.Printf("client2 failed to get lock.ResourceId is %s\n", resourceId) + wg.Done() + }() + wg.Wait() + // 3. client 1 unlock + fmt.Println("client1 prepare to unlock...") + _, err = cli.Unlock(ctx, &runtimev1pb.UnlockRequest{ + StoreName: storeName, + ResourceId: resourceId, + LockOwner: owner1, + }) + if err != nil { + panic(err) + } + fmt.Println("client1 succeeded in unlocking") + // 4. client 2 get lock + wg.Add(1) + go func() { + fmt.Println("client2 prepare to tryLock...") + owner2 := uuid.New().String() + resp, err := cli.TryLock(ctx, &runtimev1pb.TryLockRequest{ + StoreName: storeName, + ResourceId: resourceId, + LockOwner: owner2, + Expire: 10, + }) + if err != nil { + panic(err) + } + if !resp.Success { + panic("client2 failed to get lock?!") + } + fmt.Printf("client2 got lock.ResourceId is %s\n", resourceId) + // 5. client2 unlock + unlockResp, err := cli.Unlock(ctx, &runtimev1pb.UnlockRequest{ + StoreName: storeName, + ResourceId: resourceId, + LockOwner: owner2, + }) + if err != nil { + panic(err) + } + if unlockResp.Status != 0 { + panic("client2 failed to unlock!") + } + fmt.Println("client2 succeeded in unlocking") + wg.Done() + }() + wg.Wait() + fmt.Println("Demo success!") +} diff --git a/demo/sequencer/in-memory/client.go b/demo/sequencer/in-memory/client.go new file mode 100644 index 0000000000..13b8634532 --- /dev/null +++ b/demo/sequencer/in-memory/client.go @@ -0,0 +1,38 @@ +package main + +import ( + "context" + "fmt" + client "mosn.io/layotto/sdk/go-sdk/client" + runtimev1pb "mosn.io/layotto/spec/proto/runtime/v1" +) + +const ( + key = "key666" + storeName = "in-memory" +) + +func main() { + + cli, err := client.NewClient() + if err != nil { + panic(err) + } + defer cli.Close() + ctx := context.Background() + fmt.Printf("Try to get next id.Key:%s \n", key) + for i := 0; i < 10; i++ { + id, err := cli.GetNextId(ctx, &runtimev1pb.GetNextIdRequest{ + StoreName: storeName, + Key: key, + Options: nil, + Metadata: nil, + }) + if err != nil { + fmt.Print(err) + return + } + fmt.Printf("Next id:%v \n", id) + } + fmt.Println("Demo success!") +} diff --git a/docs/en/component_specs/pubsub/common.md b/docs/en/component_specs/pubsub/common.md index fee409f5d8..31cecd5b07 100644 --- a/docs/en/component_specs/pubsub/common.md +++ b/docs/en/component_specs/pubsub/common.md @@ -12,7 +12,7 @@ The json configuration file has the following structure: } } ``` -You can configure the key/value configuration items that the component cares about in the metadata. For example, [redis component configuration](https://github.com/mosn/layotto/blob/main/configs/config_apollo_health_mq.json) is as follows: +You can configure the key/value configuration items that the component cares about in the metadata. For example, [redis component configuration](https://github.com/mosn/layotto/blob/main/configs/config_redis.json) is as follows: ```json "pub_subs": { diff --git a/docs/en/component_specs/pubsub/redis.md b/docs/en/component_specs/pubsub/redis.md index 03f4fea1a3..89dd5f88fb 100644 --- a/docs/en/component_specs/pubsub/redis.md +++ b/docs/en/component_specs/pubsub/redis.md @@ -1,7 +1,7 @@ # Redis ## metadata fields -Example: configs/config_apollo_health_mq.json +Example: configs/config_redis.json | Field | Required | Description | | --- | --- | --- | diff --git a/docs/en/start/pubsub/start.md b/docs/en/start/pubsub/start.md index afe8503213..711cfb4710 100644 --- a/docs/en/start/pubsub/start.md +++ b/docs/en/start/pubsub/start.md @@ -82,7 +82,7 @@ go build After completion, the layotto file will be generated in the directory, run it: ```bash -./layotto start -c ../../configs/config_apollo_health_mq.json +./layotto start -c ../../configs/config_redis.json ``` ### Step 4. Run the Publisher program and call Layotto to publish events diff --git a/docs/zh/component_specs/lock/in-memory.md b/docs/zh/component_specs/lock/in-memory.md new file mode 100644 index 0000000000..44e293834d --- /dev/null +++ b/docs/zh/component_specs/lock/in-memory.md @@ -0,0 +1,25 @@ +# In-Memory + +## 配置项说明 + +直接使用配置:configs/config_in_memory.json + + +## 启动 layotto + +````shell +cd ${projectpath}/cmd/layotto +go build +```` +编译成功后执行: +````shell +./layotto start -c ../../configs/config_in_memory.json +```` + +## 运行 Demo + +````shell +cd ${projectpath}/demo/lock/in-memory/ + go build -o client + ./client +```` \ No newline at end of file diff --git a/docs/zh/component_specs/pubsub/common.md b/docs/zh/component_specs/pubsub/common.md index af5df8b2a6..18f6bee51a 100644 --- a/docs/zh/component_specs/pubsub/common.md +++ b/docs/zh/component_specs/pubsub/common.md @@ -13,7 +13,7 @@ json配置文件有如下结构: } ``` -您可以在metadata里配置组件关心的key/value配置。例如[redis组件的配置](https://github.com/mosn/layotto/blob/main/configs/config_apollo_health_mq.json) 如下: +您可以在metadata里配置组件关心的key/value配置。例如[redis组件的配置](https://github.com/mosn/layotto/blob/main/configs/config_redis.json) 如下: ```json "pub_subs": { diff --git a/docs/zh/component_specs/pubsub/redis.md b/docs/zh/component_specs/pubsub/redis.md index a8f56ee1d6..5d33ce0d5d 100644 --- a/docs/zh/component_specs/pubsub/redis.md +++ b/docs/zh/component_specs/pubsub/redis.md @@ -1,7 +1,7 @@ # Redis ## 配置项说明 -示例:configs/config_apollo_health_mq.json +示例:configs/config_redis.json | 字段 | 必填 | 说明 | | --- | --- | --- | diff --git a/docs/zh/component_specs/sequencer/in-memory.md b/docs/zh/component_specs/sequencer/in-memory.md new file mode 100644 index 0000000000..f5d430310f --- /dev/null +++ b/docs/zh/component_specs/sequencer/in-memory.md @@ -0,0 +1,25 @@ +# In-Memory + +## 配置项说明 + +直接使用配置:configs/config_in_memory.json + + +## 启动 layotto + +````shell +cd ${projectpath}/cmd/layotto +go build +```` +编译成功后执行: +````shell +./layotto start -c ../../configs/config_in_memory.json +```` + +## 运行 Demo + +````shell +cd ${projectpath}/demo/sequencer/in-memory/ + go build -o client + ./client +```` \ No newline at end of file diff --git a/docs/zh/start/pubsub/start.md b/docs/zh/start/pubsub/start.md index 0b3971664c..8efb706d7e 100644 --- a/docs/zh/start/pubsub/start.md +++ b/docs/zh/start/pubsub/start.md @@ -82,7 +82,7 @@ go build 完成后目录下会生成layotto文件,运行它: ```bash -./layotto start -c ../../configs/config_apollo_health_mq.json +./layotto start -c ../../configs/config_redis.json ``` ### 第四步:运行Publisher程序,调用Layotto发布事件 diff --git a/go.mod b/go.mod index c154505605..2a0523afc6 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module mosn.io/layotto go 1.14 require ( + github.com/99designs/keyring v1.2.1 // indirect github.com/Azure/go-autorest/autorest/azure/cli v0.4.2 // indirect github.com/Azure/go-autorest/autorest/validation v0.3.1 // indirect github.com/Azure/go-autorest/logger v0.2.1 // indirect diff --git a/go.sum b/go.sum index 85a7661f66..397b13129b 100644 --- a/go.sum +++ b/go.sum @@ -39,8 +39,11 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU= -github.com/99designs/keyring v1.1.5 h1:wLv7QyzYpFIyMSwOADq1CLTF9KbjbBfcnfmOGJ64aO4= +github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= +github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= github.com/99designs/keyring v1.1.5/go.mod h1:7hsVvt2qXgtadGevGJ4ujg+u8m6SpJ5TpHqTozIPqf0= +github.com/99designs/keyring v1.2.1 h1:tYLp1ULvO7i3fI5vE21ReQuj99QFSs7lGm0xWyJo87o= +github.com/99designs/keyring v1.2.1/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA= github.com/AthenZ/athenz v1.10.15 h1:8Bc2W313k/ev/SGokuthNbzpwfg9W3frg3PKq1r943I= github.com/AthenZ/athenz v1.10.15/go.mod h1:7KMpEuJ9E4+vMCMI3UQJxwWs0RZtQq7YXZ1IteUjdsc= github.com/Azure/azure-amqp-common-go/v3 v3.0.1/go.mod h1:PBIGdzcO1teYoufTKMcGibdKaYZv4avS+O6LNIp8bq0= @@ -334,8 +337,9 @@ github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= github.com/dancannon/gorethink v4.0.0+incompatible h1:KFV7Gha3AuqT+gr0B/eKvGhbjmUv0qGF43aKCIKVE9A= github.com/dancannon/gorethink v4.0.0+incompatible/go.mod h1:BLvkat9KmZc1efyYwhz3WnybhRZtgF1K929FD8z1avU= -github.com/danieljoos/wincred v1.0.2 h1:zf4bhty2iLuwgjgpraD2E9UbvO+fe54XXGJbOwe23fU= github.com/danieljoos/wincred v1.0.2/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3EJbmjhLdK9U= +github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= +github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= github.com/dapr/components-contrib v1.5.1-rc.1 h1:t7Y8jxGcNnYXYglBWuvT/A6QszfpVIICi+AGvi0aaaY= github.com/dapr/components-contrib v1.5.1-rc.1/go.mod h1:k40RvOMnDmJMSSbWZ10ajjWJ9pEuq4Z5eKxCa/yrAe8= github.com/dapr/kit v0.0.2-0.20210614175626-b9074b64d233 h1:M0dWIG8kUxEFU57IqTWeqptNqlBsfosFgsA5Ov7rJ8g= @@ -393,8 +397,9 @@ github.com/dubbogo/jsonparser v1.0.1/go.mod h1:tYAtpctvSP/tWw4MeelsowSPgXQRVHHWb github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dvsekhvalnov/jose2go v0.0.0-20180829124132-7f401d37b68a h1:mq+R6XEM6lJX5VlLyZIrUSP8tSuJp82xTK89hvBwJbU= github.com/dvsekhvalnov/jose2go v0.0.0-20180829124132-7f401d37b68a/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM= +github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM= +github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-resiliency v1.2.0 h1:v7g92e/KSN71Rq7vSThKaWIq68fL4YHvWyiUKorFR1Q= github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= @@ -891,7 +896,6 @@ github.com/kataras/go-errors v0.0.3/go.mod h1:K3ncz8UzwI3bpuksXt5tQLmrRlgxfv+52A github.com/kataras/go-serializer v0.0.4/go.mod h1:/EyLBhXKQOJ12dZwpUZZje3lGy+3wnvG7QKaVJtm/no= github.com/keighl/postmark v0.0.0-20190821160221-28358b1a94e3/go.mod h1:Pz+php+2qQ4fWYwCa5O/rcnovTT2ylkKg3OnMLuFUbg= github.com/kevinburke/go-bindata v3.22.0+incompatible/go.mod h1:/pEEZ72flUW2p0yi30bslSp9YqD9pysLxunQDdb2CPM= -github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d h1:Z+RDyXzjKE0i2sTjZ/b1uxiGtPhFy34Ou/Tk0qwN0kM= github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d/go.mod h1:JJNrCn9otv/2QP4D7SMJBgaleKpOf66PnW6F5WGNRIc= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= @@ -1303,8 +1307,9 @@ github.com/streadway/amqp v1.0.0/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1Sd github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.3.0 h1:NGXK3lHquSN08v5vWalVI/L8XU9hdzE/G6xsrze47As= +github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -1749,11 +1754,14 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211020174200-9d6173849985 h1:LOlKVhfDyahgmqa97awczplwkjzNaELFg3zRIJ13RYo= +golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211020174200-9d6173849985/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a h1:ppl5mZgokTT8uPkmYOyEUmPTr3ypaKkg5eFOGrAmxxE= +golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1980,6 +1988,7 @@ gopkg.in/check.v1 v1.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=