3

I'm making a server that can read/write from file concurrently(from goroutines populated by net/http handlers). I've created The following struct:

type transactionsFile struct {
    File  *os.File
    Mutex *sync.RWMutex
}

I'm initializing file once at the init() function. Should I close it somehow on each writing operation?

  • If you close the file, you will have to open it again at the beginning of your handler. – ifnotak Feb 19 '19 at 11:08
  • @Abdullah that's why I'm asking) Is it safe not to close the file? – Sailor Moon Feb 19 '19 at 11:12
  • 1
    `Should I close it somehow on each writing operation?` this is very specific to the use case. However, don t forget to sync to make sure data is written on disk, see https://golang.org/pkg/os/#File.Sync. –  Feb 19 '19 at 11:30

1 Answers1

4

You can't write to a closed file, so if you close it after each write operation, you also have to (re)open it before each write.

This would be quite inefficient. So instead leave it open, and only close it once your app is about to terminate (this is required because File.Write() does not guarantee that when it returns the data is written to disk). Since you're writing the file from HTTP handlers, you should implement graceful server termination, and close the file after that. See Server.Shutdown() for details.

Also, if the purpose of your shared file writing is to create some kind of logger, you could take advantage of the log package, so you would not have to use a mutex. For details, see net/http set custom logger.

icza
  • 389,944
  • 63
  • 907
  • 827
  • Does `Write()` guarantees that changes will be saved? Isn't it `Close()`'s responsibility? – Sailor Moon Feb 19 '19 at 11:28
  • @SailorMoon Yes, there is no guarantee that when `File.Write()` returns the data is written to the underlying storage unit. – icza Feb 19 '19 at 11:29
  • Neither `Write()` nor `Close()` guarantee that the changes are actually written. You can use `Sync()` and check the returned error before closing the file. – ifnotak Feb 19 '19 at 13:00
  • @Abdullah Yes, it does not guarantee that the data written will appear on the disk right away. But if `Close()` does not return an error, the data will be written to disk eventually, even if the app terminates. – icza Feb 19 '19 at 13:18
  • @icza Yes, this is true unless there is a disk failure which is a bigger problem all together. – ifnotak Feb 20 '19 at 00:10