如何将MongoDB数据库传递给Go协程?

huangapple go评论78阅读模式
英文:

how to pass a MongoDB database to a GO routine?

问题

我是你的中文翻译,以下是翻译好的部分:

我是Go的新手,我正在尝试编写一个简单的程序,该程序遍历MongoDB数据库中的所有用户,并针对每个用户遍历他的所有帖子,使用'mgo'包。

这段代码是正常工作的,

但是,如果我尝试将对handleUser(db, &result)的调用更改为go handleUser(db, &result),则handleUser内部的第二个查询不起作用。

我怀疑会话已经关闭,因为'main'已经完成了,我是正确的吗?如果是这样,如何处理这种情况?

英文:

I'm new to Go and I'm trying to write a simple program that iterates over all users in the MongoDB database and for each user iterates over all of his posts, using the 'mgo' package.

package main

import (
	"fmt"
	"labix.org/v2/mgo"
	"labix.org/v2/mgo/bson"
)

type User struct {
	Id string
	Email string
}

type Post struct {
	Id string
	Description string
}

func handleUser(db *mgo.Database, user *User) {
	fmt.Println("ID: ", user.Id, " EMAIL: ", user.Email)

	result := Post{}

	iter := db.C("posts").Find(bson.M{"user_id": user.Id}).Iter()

	for iter.Next(&result) {
		fmt.Println("POST ID: ", result.Id, " POST DESCRIPTION: ", result.Description)
	}
}

func main() {
	session, err := mgo.Dial("localhost")

	if err != nil {
		panic(err)
	}

	defer session.Close()

	db := session.DB("mydb")

	result := User{}

	iter := db.C("users").Find(nil).Iter()
	for iter.Next(&result) {
		handleUser(db, &result)
	}	
}

this is working just fine,
but if I try to change the call to handleUser(db, &result) to go handleUser(db, &result) the second query inside handleUser doesn't do anything.

I suspect that the session is already closed because 'main' already finished, am I correct? if so, what is the way to handle such scenario ?

答案1

得分: 7

你对于specs的理解是正确的,它们定义了当main函数返回时,所有的goroutine都会被终止:

当main函数返回时,程序退出。它不会等待其他(非main)的goroutine完成。

有两种选择。

  • 在main函数的末尾与你的goroutine进行同步。可以使用一个“done”通道或者sync.WaitGroup

  • 在适当的地方可以使用一个阻塞的空select语句:

    select{} // 永远阻塞

英文:

You're right about the specs, they define that when main returns, all goroutines are killed:

> When the function main returns, the program exits. It does not wait for other (non-main) goroutines to complete.

There are two options.

  • Synchronize with your goroutines at the end of main. A "done" chanel can be used or a sync.WaitGroup.

  • Where appropriate a blocking empty select statement could be used:

    select{} // Non busy block forever

huangapple
  • 本文由 发表于 2013年4月15日 17:35:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/16011902.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定