【发布时间】:2018-03-13 23:01:35
【问题描述】:
我有一个配置,它定义了许多实例 (SomeConfigItems),它们为每个实例创建了一个 thing()。
那个东西是一个包含包返回的结构,其中包含价格(float64)和嵌套结构。嵌套结构维护交易图。
问题是我能够遍历 thing.Streams.Trades 并从我的 main() 的 for{} 循环中实时查看所有交易。我看不到更新的东西。价格即使有时在处理程序中设置。
我很难理解嵌套结构如何包含数据但不包含价格。我觉得好像我错过了范围界定、goroutines 或可能用于实例化新对象的指针的东西。
任何帮助将不胜感激,同时我将继续阅读。我已将代码简化为看起来相关的内容。
main.go:
package main
import thing
var Things []thing.Handler
for _, name := range SomeConfigItems {
handler := thing.New(name)
Things = append(Things, handler)
}
for {
for _, t := range Things {
log.Info("Price: ", t.Price) // This is set to 0 every iteration, but I can actively data in thing.Streams.Trades
}
}
thing.go:
package thing
import streams
type Handler struct {
Name string
Price float64
Streams streams.Streams
}
func New(name string) (h Handler, err error) {
stream, err := streams.New(strings.ToLower(name))
h = Handler{
Name: name,
Price: "0.0"
Streams: stream,
}
go h.handler()
return h, err
}
func (bot *Handler) handler() {
var currentPrice float64
for {
currentPrice = external.GetPrice(bot.Name).Price // Validated that this returns a float64
bot.Price = currentPrice // Verified that this is updated immediately after in this context.
// Unable to see Price updated from outer context.
}
}
streams.go:
package streams
type Streams struct {
Trades
}
type State struct {
Price string `json:"p"`
Quantity string `json:"q"`
}
type Trades struct {
Trades map[float64]float64
TradeMutex sync.Mutex
Updates chan State
}
func New(name string) (s Streams, err error) {
p := newTradeStream(name)
s = Streams{
Trades: p,
}
return s, err
}
func newTradeStream(name string) (ts Trades) {
ts = Trades{}
ts.Trades = make(map[float64]float64, MaxDepth)
ts.Updates = make(chan State, 500)
// ... Other watchdog code
return ts
}
注意:
我在多个位置添加了一些调试日志记录。在机器人处理程序中,价格被打印(成功),然后更新,然后再次打印(成功)——在 handler() 函数中显示价格设置没有间隙。
在 main() for{} 循环中添加相同类型的调试时,我尝试设置递增计数器并分配 thing.Price 的值——在每个循环上打印 thing.Price 会导致 0,即使我在同一个循环中设置价格(并验证它是否已设置),在下一次迭代中它会回到 0。
这种行为是我认为我遗漏了一些非常基本的东西的原因。
【问题讨论】:
-
刚刚开始,
thing.New返回处理程序的副本。一旦处理程序在同一个结构上运行,您需要添加某种同步,因为这会导致数据竞争。 -
谢谢,我找到了我认为您正在引用的部分,并删除了取消引用原始 BotHandler 结构的 *。我希望这可能会解决问题,因为它听起来像我遇到的问题,但结果相同。
-
不,删除
*会更改接收者类型,因此您还有另一个副本。我会备份并回顾一些基础知识,因为这里有许多基础问题增加了混乱。 -
感谢 @JimB 抽出宝贵时间发表评论。我从一开始就确保我没有遗漏任何东西,现在我发现我的方法中存在很多问题。