callcache

package module
v0.0.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 18, 2022 License: MIT Imports: 3 Imported by: 0

README

callcache

GoDoc Test Status

Package callcache provides a duplicate call suppression mechanism with cache.
This is inspired by github.com/Songmu/smartcache.

Documentation

Overview

Package callcache provides a duplicate call suppression mechanism with cache.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Dispatcher

type Dispatcher struct {
	// contains filtered or unexported fields
}

Dispatcher handles each call.

Example
package main

import (
	"fmt"
	"time"

	"github.com/daisuzu/callcache"
)

func main() {
	dispatcher := callcache.NewDispatcher(1*time.Minute, 10*time.Second)

	v, err := dispatcher.Do("key", func() (interface{}, error) {
		return "example", nil
	})

	fmt.Println(v, err)
}
Output:

example <nil>

func NewDispatcher

func NewDispatcher(expiration, updateInterval time.Duration) *Dispatcher

NewDispatcher creates a new Dispatcher of function or method calls. expiration is the period to keep the execution result. If updateInterval is greater than 0, the cache of the execution result will be updated in the background when the elapsed time from the previous execution is exceeded.

Example (Expiration)
package main

import (
	"fmt"
	"sync"
	"time"

	"github.com/daisuzu/callcache"
)

func main() {
	dispatcher := callcache.NewDispatcher(1*time.Nanosecond, 0)

	wg := sync.WaitGroup{}
	results := make([]interface{}, 3)
	for i := range results {
		wg.Add(1)
		results[i], _ = dispatcher.Do("key", func() (interface{}, error) {
			defer wg.Done()
			fmt.Printf("Do: #%d\n", i+1)
			return i + 1, nil
		})
		wg.Wait()
		time.Sleep(1 * time.Nanosecond)
	}

	for _, v := range results {
		fmt.Println(v)
	}
}
Output:

Do: #1
Do: #2
Do: #3
1
2
3
Example (UpdateInterval)
package main

import (
	"fmt"
	"sync"
	"time"

	"github.com/daisuzu/callcache"
)

func main() {
	dispatcher := callcache.NewDispatcher(1*time.Minute, 1*time.Nanosecond)

	wg := sync.WaitGroup{}
	results := make([]interface{}, 3)
	for i := range results {
		wg.Add(1)
		results[i], _ = dispatcher.Do("key", func() (interface{}, error) {
			defer wg.Done()
			fmt.Printf("Do: #%d\n", i+1)
			return i + 1, nil
		})
		wg.Wait()
		time.Sleep(1 * time.Nanosecond)
	}

	for _, v := range results {
		fmt.Println(v)
	}
}
Output:

Do: #1
Do: #2
Do: #3
1
1
2

func (*Dispatcher) Do

func (d *Dispatcher) Do(key string, fn func() (interface{}, error)) (interface{}, error)

Do returns the execution result of fn associated with the given key. If there is a valid execution result, it is reused instead of the return value of fn.

Example (ConcurrentDifferentKeys)
package main

import (
	"fmt"
	"sync"
	"time"

	"github.com/daisuzu/callcache"
)

func main() {
	dispatcher := callcache.NewDispatcher(1*time.Minute, 10*time.Second)

	wg := sync.WaitGroup{}
	results := make([]interface{}, 3)
	for i := range results {
		wg.Add(1)
		go func(i int) {
			results[i], _ = dispatcher.Do(fmt.Sprintf("key%d", i+1), func() (interface{}, error) {
				fmt.Printf("Do: #%d\n", i+1)
				return i + 1, nil
			})
			wg.Done()
		}(i)
	}
	wg.Wait()

	for _, v := range results {
		fmt.Println(v)
	}
}
Output:

Do: #1
Do: #2
Do: #3
1
2
3
Example (ConcurrentSameKey)
package main

import (
	"fmt"
	"sync"
	"sync/atomic"
	"time"

	"github.com/daisuzu/callcache"
)

func main() {
	dispatcher := callcache.NewDispatcher(1*time.Minute, 10*time.Second)

	var value int32

	wg := sync.WaitGroup{}
	results := make([]interface{}, 3)
	for i := range results {
		wg.Add(1)
		go func(i int) {
			results[i], _ = dispatcher.Do("key", func() (interface{}, error) {
				fmt.Println("Do")
				return atomic.AddInt32(&value, 1), nil
			})
			wg.Done()
		}(i)
	}
	wg.Wait()

	for _, v := range results {
		fmt.Println(v)
	}
}
Output:

Do
1
1
1
Example (Multiple)
package main

import (
	"fmt"
	"time"

	"github.com/daisuzu/callcache"
)

func main() {
	dispatcher := callcache.NewDispatcher(1*time.Minute, 10*time.Second)

	results := make([]interface{}, 3)
	for i := range results {
		results[i], _ = dispatcher.Do("key", func() (interface{}, error) {
			fmt.Printf("Do: #%d\n", i+1)
			return i + 1, nil
		})
	}

	for _, v := range results {
		fmt.Println(v)
	}
}
Output:

Do: #1
1
1
1

func (*Dispatcher) Remove

func (d *Dispatcher) Remove(key string)

Remove removes the execution result of the given key.

Example
package main

import (
	"fmt"
	"time"

	"github.com/daisuzu/callcache"
)

func main() {
	dispatcher := callcache.NewDispatcher(1*time.Minute, 10*time.Second)

	v1, _ := dispatcher.Do("key", func() (interface{}, error) {
		fmt.Println("Do: #1")
		return 1, nil
	})
	dispatcher.Remove("key")
	v2, _ := dispatcher.Do("key", func() (interface{}, error) {
		fmt.Println("Do: #2")
		return 2, nil
	})

	fmt.Println(v1)
	fmt.Println(v2)
}
Output:

Do: #1
Do: #2
1
2

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL