我试图在go webserver应用程序中运行一个简单的键值存储,它应该存储一些信息。
问题是,我只能创建它的一个实例,因为它写入磁盘和文件夹是锁定的,所以我需要找到使用我的Web服务器访问键值存储。
因此每个当前实例都可以访问它(读/写)。 我该怎么做?
目前我的应用看起来像这样:https://play.golang.org/p/_SmGBZlP0Vi 我想要使用的包是:https://github.com/peterbourgon/diskv
基本上我会在main之前创建一个实例并将键值存储的实例传递给rtt函数,但这似乎不能直接在go中实现。或者我做错了什么?
答案 0 :(得分:1)
首先使用键值存储的单个实例创建一个包,并使连接成为您连接一次的包变量,然后保持打开以供将来使用。这里有一些伪代码示例:
package kvstore
var conn *diskv.Conn // or whatever the type of the conn is
func Connect(...) {
// crate connection and fill conn
conn = diskv.New(...)
}
func Write(k, v []byte) error {
return conn.Write(k, v)
}
那样你有一个全球性的#34;可以在任何地方使用的连接。只需在任何地方拨打kvstore.Write(...)
即可写入商店。
如果您的应用程序使用多个可以访问kvstore的goroutine(可能 - 取决于您使用的包是否已经为您执行此操作)需要同步访问权限。您可以使用互斥锁进行连接:
var (
conn *diskv.Conn // or whatever the type of the conn is
mutex sync.Mutex
)
func Write(k, v []byte) error {
// everywhere you use the conn object, lock the mutex before and unlock after
mutex.Lock()
defer mutex.Unlock()
return conn.Write(k, v)
}
您还可以使用actor模式。这里有一篇由Peter Bourgon撰写的文章,解释了actor pattern。使用actor模式,我们可以确保conn对象仅用于一个goroutine,因为不需要使用互斥锁。
package kvstore
import "github.com/peterbourgon/diskv"
var conn *diskv.Diskv
// Connect opens the global diskv db
func Connect(dir string) {
flatTransform := func(s string) []string { return []string{} }
conn = diskv.New(diskv.Options{
BasePath: dir,
Transform: flatTransform,
CacheSizeMax: 1024 * 1024,
})
}
// Write writes to the global diskv db
func Write(k string, v []byte) error {
return conn.Write(k, v)
}
// Read reads from the global diskv db
func Read(k string) ([]byte, error) {
return conn.Read(k)
}
// Erase deletes a key from the global discv db
func Erase(k string) error {
return conn.Erase(k)
}
package main
import (
"github.com/tehsphinx/diskv"
)
func main() {
// call this once in startup sequence.
kvstore.Connect("my-data-dir")
// use this anywhere to write to key value store
kvstore.Write("alpha", []byte{'1', '2', '2'})
// use this anywhere to read from kvstore
kvstore.Read("alpha")
// use this anywhere to delete from kvstore
kvstore.Erase("alpha")
}
只需将其复制到两个不同的文件夹中即可。它有效。