Changeset 608 in code for trunk/msgstore_fs.go


Ignore:
Timestamp:
Oct 6, 2021, 9:41:39 AM (4 years ago)
Author:
contact
Message:

msgstore_fs: add limit on number of opened files

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/msgstore_fs.go

    r591 r608  
    1515)
    1616
    17 const fsMessageStoreMaxTries = 100
     17const (
     18        fsMessageStoreMaxFiles = 20
     19        fsMessageStoreMaxTries = 100
     20)
    1821
    1922func escapeFilename(unsafe string) (safe string) {
     
    6669}
    6770
     71type fsMessageStoreFile struct {
     72        *os.File
     73        lastUse time.Time
     74}
     75
    6876// fsMessageStore is a per-user on-disk store for IRC messages.
    6977type fsMessageStore struct {
    7078        root string
    7179
    72         files map[string]*os.File // indexed by entity
     80        // Write-only files used by Append
     81        files map[string]*fsMessageStoreFile // indexed by entity
    7382}
    7483
     
    7988        return &fsMessageStore{
    8089                root:  filepath.Join(root, escapeFilename(username)),
    81                 files: make(map[string]*os.File),
     90                files: make(map[string]*fsMessageStoreFile),
    8291        }
    8392}
     
    127136        }
    128137
    129         // TODO: enforce maximum open file handles (LRU cache of file handles)
    130138        f := ms.files[entity]
    131139
     
    133141        path := ms.logPath(network, entity, t)
    134142        if f == nil || f.Name() != path {
    135                 if f != nil {
    136                         f.Close()
    137                 }
    138 
    139143                dir := filepath.Dir(path)
    140144                if err := os.MkdirAll(dir, 0750); err != nil {
     
    142146                }
    143147
    144                 var err error
    145                 f, err = os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0640)
     148                ff, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0640)
    146149                if err != nil {
    147150                        return "", fmt.Errorf("failed to open message log file %q: %v", path, err)
    148151                }
    149152
     153                if f != nil {
     154                        f.Close()
     155                }
     156                f = &fsMessageStoreFile{File: ff}
    150157                ms.files[entity] = f
    151158        }
    152159
    153         msgID, err := nextFSMsgID(network, entity, t, f)
     160        f.lastUse = time.Now()
     161
     162        if len(ms.files) > fsMessageStoreMaxFiles {
     163                entities := make([]string, 0, len(ms.files))
     164                for name := range ms.files {
     165                        entities = append(entities, name)
     166                }
     167                sort.Slice(entities, func(i, j int) bool {
     168                        a, b := entities[i], entities[j]
     169                        return ms.files[a].lastUse.Before(ms.files[b].lastUse)
     170                })
     171                entities = entities[0 : len(entities)-fsMessageStoreMaxFiles]
     172                for _, name := range entities {
     173                        ms.files[name].Close()
     174                        delete(ms.files, name)
     175                }
     176        }
     177
     178        msgID, err := nextFSMsgID(network, entity, t, f.File)
    154179        if err != nil {
    155180                return "", fmt.Errorf("failed to generate message ID: %v", err)
Note: See TracChangeset for help on using the changeset viewer.