<p><strong>edit</strong>: Thanks to <a href="https://github.com/takching">takching</a> and <a href="/u/korylprince">/u/korylprince</a> for helping me fix this. I'm pleased to say that <a href="https://github.com/cathalgarvey/listless">listless</a> now basically works, allowing you to host a simple discussion list using any IMAP/SMTP account, instead of relying on Google, Yahoo, or maintaining your own email stack just to run Mailman. :)</p>
<hr/>
<p>Hi all,</p>
<p>Not normally one to post for help without really trying to fix first by myself, but I'm at wits end.</p>
<p>I'm working on a project right now <a href="https://github.com/cathalgarvey/listless">to permit people to host email discussion lists using only IMAP/SMTP</a>: In fact, I found it very strange that nobody else seems to have done this already. The basic architecture is: Config file with account details, and a lua script to run on any incoming mail which does the work of handling, storing, modifying, and dispatching mail. Indeed, you could use this to write a Lua-scripted email bot that has nothing to do with a discussion list or mailing list, but that's not the primary goal.</p>
<p>For this project, I chose to use [bolt as the database backend](github.com/boltdb/bolt), which currently is only being written to store list archives (optionally, as scripted in the Lua bits) and to store/access/modify list members/subscribers' entries.</p>
<p>The problem I'm having is that when adding users to the database, the first user is entered OK, but subsequent users' values clobber them.</p>
<p>That is, each call (in lua) to <code>database:UpdateSubscriber("foo@bar.com", foometa)</code> calls a <code>db.Update(func(tx *bolt.Tx) error { ... })</code> method where foometa is JSON marshalled and entered into a bucket called "members". The first such call leads to a database bucket like this:</p>
<pre><code>members: {
foo@bar.com: {
name: Foo
email: foo@bar.com
moderator: false
}
}
</code></pre>
<p>..But the second call, with a different user email and meta object (created independently, that is) with different values, say <code>database:UpdateSubscriber("baz@qux.com", bazmeta)</code>, (where baz is a mod) leads to this:</p>
<pre><code>members: {
foo@bar.com: {
name: Baz
email: baz@qux.com
moderator: true
}
baz@qux.com: {
name: Baz
email: baz@qux.com
moderator: true
}
</code></pre>
<p>I'm <strong>not</strong> using global variables for this part of my code, nor is there any scope leakage I'm aware of, or ambiguous variable naming, etcetera etcetera. I was wary of some shenanigans in the Lua layer so I rewrote some of the database methods/bindings and instantiated my foos/bazzes separately to be sure. The problem persists.</p>
<p>This is very basic boltdb usage, which is what prompts me to write it here; either someone else has encountered this before, or it's undocumented, or I'm just an idiot. Any of the three should be suitable entertaining for others here, methinks.</p>
<p>It's a big ask, but if anyone feels like helping, <a href="https://github.com/cathalgarvey/listless/issues/2">I documented the bug and how to reproduce on the project issue tracker</a>. I'd sincerely like to learn what's going awry here! This bug may be one of the last things stopping this project from working overall in a basic way so I'm keen to squash it.</p>
<p>Big thanks for any insight ye can offer!</p>
<hr/>**评论:**<br/><br/>korylprince: <pre><pre><code>diff --git a/database.go b/database.go
index cf712b4..575f759 100644
--- a/database.go
+++ b/database.go
@@ -217,7 +217,7 @@ func (db *ListlessDB) goGetAllSubscribers(modsOnly bool) (subscribers []string)
db.View(func(tx *bolt.Tx) error {
members := tx.Bucket([]byte("members"))
c := members.Cursor()
- for email, metabytes := c.First(); email != nil; email, _ = c.Next() {
+ for email, metabytes := c.First(); email != nil; email, metabytes = c.Next() {
log.Printf("Iterating over database member: %s, meta: %s", email, string(metabytes))
meta := MemberMeta{}
err := json.Unmarshal(metabytes, &meta)
</code></pre>
<p>After debugging for about 45 minutes, it came to this. I knew your boltdb code was fine. You were just using the <code>metabytes</code> from <code>c.First()</code> instead of updating it on each iteration. Fun problem!</p></pre>anacrolix: <pre><p>Fix my bugs plz</p></pre>cathalgarvey: <pre><p>OMG thank you! I had been meaning to switch to ForEach anyway..</p>
<p>That's a subtle and irritating bug, I wasn't even looking there for the source!</p></pre>jayposs: <pre><p>Can't explain your results, but are you converting the key from a string to a byte slice, []byte(key) ?</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传