"sequential"というファイルに書き込む必要があるのは、2つの並行するゴルーチンがファイルに書き込むことができないということです。はい、writeToFile()
関数でロックを使用すると、あなたのAjaxリクエストの処理が(部分的に)順次になることもあります。
私が提案するのは、アプリケーションを起動するときにファイルを一度開くことです。ファイルへの書き込みを担当する単一のゴルーチンを指定します。他のgoroutinesはそれを行うべきではありません。
バッファされたチャネルを使用して、ファイルに書き込まれるデータを送信します。これにより、ajaxリクエストは非ブロッキングになりますが、ファイルは同時に並行/並行して書き込まれません。
このように、データが実際にファイルに書き込まれている間(応答時間が速い)、Ajaxリクエストは待つ必要がないことに注意してください。これは問題である場合とそうでない場合があります。たとえば、後で書き込みが失敗した場合、Ajaxレスポンスはすでにコミットされている可能性があります。>クライアントに失敗を通知する機会はありません。
それを行う方法の例:(それが閉じていたときに、writeToFile()
のループが終了すると、ファイルが閉じられます。
var (
f *os.File
datach = make(chan []byte, 100) // Buffered channel
)
func init() {
// Open file for appending (create if doesn't exist)
var err error
f, err = os.OpenFile("data.txt", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0666)
if err != nil {
panic(err)
}
// Start goroutine which writes to the file
go writeToFile()
}
func writeToFile() {
// Loop through any data that needs to be written:
for data := range datach {
if _, err := f.Write(data); err != nil {
// handle error!
}
}
// We get here if datach is closed: shutdown
f.Close()
}
func ajaxHandler(w http.ResponseWriter, r *http.Request) {
// Assmeble data that needs to be written (appended) to the file
data := []byte{1, 2, 3}
// And send it:
datach <- data
}
アプリから優雅に終了するには、あなたはdatach
チャネルを閉じる必要がありますキャッシュされたデータをフラッシュし、OSリソースを解放する)。
ファイルにテキストを書き込みたい場合は、あなたがこのようなdata
チャンネル宣言してもよい:
var datach = make(chan string, 100) // Buffered channel
をし、ファイルに書き込みFile.WriteString()
を使用することがあります。
if _, err := f.WriteString(data); err != nil {
// handle error!
}
'ミューテックス.Lockは、ゴルーチン内からのリソースへの排他的なアクセスを保証するために使用されます。グローバルリソースを読み書きしようとするいくつかのゴルーチンがある場合に便利です。ファイルへの書き込みはブロックI/Oであり、そのゴルーチンを自然にブロックする必要があります。 – PieOhPah