diff --git a/context.go b/context.go index 4bc11b95..0bd7cfdc 100644 --- a/context.go +++ b/context.go @@ -85,3 +85,15 @@ func (c *Context) ForEach(fn func(k string, v interface{}) interface{}) []interf return ret } + +// Clone clones context +func (c *Context) Clone() *Context { + c.lock.RLock() + defer c.lock.RUnlock() + newCtx := NewContext() + c.ForEach(func(key string, value interface{}) interface{} { + newCtx.Put(key, value) + return nil + }) + return newCtx +} diff --git a/context_test.go b/context_test.go index 07d7d851..2eb47f57 100644 --- a/context_test.go +++ b/context_test.go @@ -37,3 +37,24 @@ func TestContextIteration(t *testing.T) { } } } + +func TestContextClone(t *testing.T) { + ctxOrg := NewContext() + for i := 0; i < 10; i++ { + ctxOrg.Put(strconv.Itoa(i), i) + } + + ctx := ctxOrg.Clone() + values := ctx.ForEach(func(k string, v interface{}) interface{} { + return v.(int) + }) + if len(values) != 10 { + t.Fatal("fail to iterate context") + } + for _, i := range values { + v := i.(int) + if v != ctx.GetAny(strconv.Itoa(v)).(int) { + t.Fatal("value not equal") + } + } +}