Go 持续接收JSON并根据时间段写入磁盘的最佳方式
我很难想出一个解决方案来不断地接收JSON并将其附加到一个切片,然后根据设置的时间周期性地将其写入磁盘。我想出了一个解决方案,但是在没有任何同步的情况下读/写同一个片Go 持续接收JSON并根据时间段写入磁盘的最佳方式,go,Go,我很难想出一个解决方案来不断地接收JSON并将其附加到一个切片,然后根据设置的时间周期性地将其写入磁盘。我想出了一个解决方案,但是在没有任何同步的情况下读/写同一个片 package main import ( "encoding/json" "fmt" "io/ioutil" "runtime" "strconv" "time" ) type Message map[string]interface{} type Messages []Mes
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"runtime"
"strconv"
"time"
)
type Message map[string]interface{}
type Messages []Message
var (
messages Messages
)
func main() {
c := make(chan Message)
var messages Messages
go func() {
tick := time.Tick(200 * time.Millisecond)
for {
select {
case <-tick:
mb := []byte(`{ "glossary": { "title": "example glossary", "GlossDiv": { "title": "S", "GlossList": { "GlossEntry": { "ID": "SGML", "SortAs": "SGML", "GlossTerm": "Standard Generalized Markup Language", "Acronym": "SGML", "Abbrev": "ISO 8879:1986", "GlossDef": { "para": "A meta-markup language, used to create markup languages such as DocBook.", "GlossSeeAlso": ["GML", "XML"] }, "GlossSee": "markup" } } } } }`)
var message Message
json.Unmarshal(mb, &message)
c <- message
}
}
}()
go func() {
tick := time.Tick(30 * time.Second)
for {
select {
case <-tick:
content, _ := json.Marshal(messages)
now := time.Now().Unix()
filename := "test" + strconv.FormatInt(now, 10) + ".json"
err := ioutil.WriteFile(filename, content, 0644)
if err != nil {
panic(err)
}
messages = nil
}
}
}()
for {
newmessage := <-c
messages = append(messages, newmessage)
}
}
主程序包
进口(
“编码/json”
“fmt”
“io/ioutil”
“运行时”
“strconv”
“时间”
)
键入消息映射[字符串]接口{}
键入Messages[]消息
变量(
信息
)
func main(){
c:=制造(成龙信息)
var消息
go func(){
滴答声:=时间滴答声(200*时间毫秒)
为了{
挑选{
case您的解决方案看起来不错,但同步部分除外:
var (
messages Messages
lock sync.Mutex
)
...
newmessage := <-c
lock.Lock()
messages = append(messages, newmessage)
lock.Unlock()
var(
信息
锁同步
)
...
newmessage:=您的解决方案看起来不错,但同步部分除外:
var (
messages Messages
lock sync.Mutex
)
...
newmessage := <-c
lock.Lock()
messages = append(messages, newmessage)
lock.Unlock()
var(
信息
锁同步
)
...
newmessage:=这是一个尽可能少锁定并尽量减少分配的版本。它也相对简单且可移植
它使用单一选择来避免额外的锁定机制,并异步写入json文件以防止阻塞使用者通道
有一个专用JSON WorkWorkWork,它阻止了在主选择中间需要一个附加的JIT同步机制的异步调用。
我还添加了正确完成程序所需的机制(即:关闭生产者、耗尽消费者、耗尽消息、等待磁盘刷新)
主程序包
进口(
“编码/json”
“日志”
“操作系统”
“操作系统/信号”
“同步”
“时间”
)
键入消息映射[字符串]接口{}
键入Messages[]消息
func main(){
c:=制造(成龙信息)
go func(){
滴答声:=时间滴答声(200*时间毫秒)
s:=制造(转换操作信号)
信号。通知
为了{
挑选{
case这是一个尽可能少锁定并尽量减少分配的版本。它也相对简单和可移植
它使用单一选择来避免额外的锁定机制,并异步写入json文件以防止阻塞使用者通道
有一个专用JSON WorkWorkWork,它阻止了在主选择中间需要一个附加的JIT同步机制的异步调用。
我还添加了正确完成程序所需的机制(即:关闭生产者、耗尽消费者、耗尽消息、等待磁盘刷新)
主程序包
进口(
“编码/json”
“日志”
“操作系统”
“操作系统/信号”
“同步”
“时间”
)
键入消息映射[字符串]接口{}
键入Messages[]消息
func main(){
c:=制造(成龙信息)
go func(){
滴答声:=时间滴答声(200*时间毫秒)
s:=制造(转换操作信号)
信号。通知
为了{
挑选{
案例
package main
import (
"encoding/json"
"log"
"os"
"os/signal"
"sync"
"time"
)
type Message map[string]interface{}
type Messages []Message
func main() {
c := make(chan Message)
go func() {
tick := time.Tick(200 * time.Millisecond)
s := make(chan os.Signal)
signal.Notify(s)
for {
select {
case <-s:
close(c)
return
case <-tick:
mb := []byte(`{ "glossary": { "title": "example glossary", "GlossDiv": { "title": "S", "GlossList": { "GlossEntry": { "ID": "SGML", "SortAs": "SGML", "GlossTerm": "Standard Generalized Markup Language", "Acronym": "SGML", "Abbrev": "ISO 8879:1986", "GlossDef": { "para": "A meta-markup language, used to create markup languages such as DocBook.", "GlossSeeAlso": ["GML", "XML"] }, "GlossSee": "markup" } } } } }`)
var message Message
json.Unmarshal(mb, &message)
c <- message
}
}
}()
var msgPool = sync.Pool{
New: func() interface{} {
return Messages{}
},
}
var wg sync.WaitGroup
wg.Add(1)
defer wg.Wait()
cMessages := make(chan Messages)
go func() {
defer wg.Done()
for messages := range cMessages {
log.Println("saved", len(messages), "messages")
// content, _ := json.Marshal(messages)
// now := time.Now().Unix()
// filename := "test" + strconv.FormatInt(now, 10) + ".json"
// err := ioutil.WriteFile(filename, content, 0644)
// if err != nil {
// log.Println(err)
// }
msgPool.Put(messages)
}
}()
messages := msgPool.Get().(Messages)
save := time.Tick(1 * time.Second)
for {
select {
case newmessage, ok := <-c:
if !ok {
<-save
cMessages <- messages
close(cMessages)
return
}
messages = append(messages, newmessage)
case <-save:
cMessages <- messages
messages = msgPool.Get().(Messages)
messages = messages[:0]
}
}
}