用goroutines&阿朗戈

时间:2016-10-03 23:05:47

标签: go

我正在尝试将〜40k文件解析为JSON并将它们保存到ArangoDB(这是我的4fun项目的一部分)。这可以简化为:

func walkRepository(task *RepositoryProcessingTask) {
    filepath.Walk(task.Repository.Path, func(path string, info os.FileInfo, err error) error {
        // ...
        go parseFile(task, file)
        // ...
        return nil
    })
}

func parseFile(task *RepositoryProcessingTask, file *RepositoryFile) {
    <- task.routinesChannel
    defer finishProcessingFile(task)

    // Saves to ArangoDB (opens http connection)
    err = db.Col("File").Save(file)

    // ...
}

所以,基本上,我正在产生40k例程。由于每个例程打开文件和http套接字到ArangoDB(我使用arangGO.v2),我很容易达到1k打开文件限制。

我试图通过channel-semaphore限制并行运行的例程数量,但没有运气:

const (
    maxRunningRoutines = 256
)

// on task creation
task.routinesChannel = make(chan int32, maxRunningRoutines)

// on task start
for i := int32(0) ; i < maxRunningRoutines ; i += 1 {
    task.routinesChannel <- i
}

// when parsing completes
task.routinesChannel <- processedFiles

最后,我增加了开放文件限制,但它会导致程序崩溃:

runtime/cgo: pthread_create failed: Resource temporarily unavailable
SIGABRT: abort
PC=0x7fcddd12c5f7 m=2

goroutine 0 [idle]:

...

goroutine 81348 [chan receive]:
net/http.(*Transport).getConn.func2.1(0xcc732b2120, 0xc8200ec0c0, 0x959c08)
        /usr/lib/golang/src/net/http/transport.go:698 +0x48
created by net/http.(*Transport).getConn.func2
        /usr/lib/golang/src/net/http/transport.go:702 +0x70

我的猜测是,DB客户端产生的HTTP连接没有关闭ASAP,这会导致麻烦。但我怎么能解决它并证明这是真正的原因?

0 个答案:

没有答案