forked from ProtonMail/gluon
-
Notifications
You must be signed in to change notification settings - Fork 0
/
builder.go
127 lines (113 loc) · 3.67 KB
/
builder.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package gluon
import (
"crypto/tls"
"fmt"
"io"
"os"
"time"
"github.com/ProtonMail/gluon/async"
"github.com/ProtonMail/gluon/db"
"github.com/ProtonMail/gluon/imap"
"github.com/ProtonMail/gluon/internal/backend"
"github.com/ProtonMail/gluon/internal/db_impl/sqlite3"
"github.com/ProtonMail/gluon/internal/session"
"github.com/ProtonMail/gluon/limits"
"github.com/ProtonMail/gluon/profiling"
"github.com/ProtonMail/gluon/reporter"
"github.com/ProtonMail/gluon/store"
"github.com/ProtonMail/gluon/version"
"github.com/sirupsen/logrus"
)
type serverBuilder struct {
dataDir string
databaseDir string
delim string
loginJailTime time.Duration
tlsConfig *tls.Config
idleBulkTime time.Duration
inLogger io.Writer
outLogger io.Writer
versionInfo version.Info
cmdExecProfBuilder profiling.CmdProfilerBuilder
storeBuilder store.Builder
reporter reporter.Reporter
disableParallelism bool
imapLimits limits.IMAP
uidValidityGenerator imap.UIDValidityGenerator
panicHandler async.PanicHandler
dbCI db.ClientInterface
}
func newBuilder() (*serverBuilder, error) {
return &serverBuilder{
delim: "/",
cmdExecProfBuilder: &profiling.NullCmdExecProfilerBuilder{},
storeBuilder: &store.OnDiskStoreBuilder{},
reporter: &reporter.NullReporter{},
idleBulkTime: 500 * time.Millisecond,
imapLimits: limits.DefaultLimits(),
uidValidityGenerator: imap.DefaultEpochUIDValidityGenerator(),
panicHandler: async.NoopPanicHandler{},
dbCI: sqlite3.NewBuilder(),
}, nil
}
func (builder *serverBuilder) build() (*Server, error) {
if builder.dataDir == "" {
dir, err := os.MkdirTemp("", "gluon-*")
if err != nil {
return nil, err
}
builder.dataDir = dir
}
if err := os.MkdirAll(builder.dataDir, 0o700); err != nil {
return nil, fmt.Errorf("failed to access or create local cache: %w", err)
}
if builder.databaseDir == "" {
dir, err := os.MkdirTemp("", "gluon-*")
if err != nil {
return nil, err
}
builder.databaseDir = dir
}
if err := os.MkdirAll(builder.databaseDir, 0o700); err != nil {
return nil, err
}
backend, err := backend.New(
builder.dataDir,
builder.databaseDir,
builder.storeBuilder,
builder.delim,
builder.loginJailTime,
builder.imapLimits,
builder.panicHandler,
builder.dbCI,
)
if err != nil {
return nil, err
}
// Defer delete all the previous databases from removed user accounts. This is required since we can't
// close ent databases on demand.
if err := db.DeleteDeferredDBFiles(builder.databaseDir); err != nil {
logrus.WithError(err).Error("Failed to remove old database files")
}
s := &Server{
dataDir: builder.dataDir,
databaseDir: builder.databaseDir,
backend: backend,
sessions: make(map[int]*session.Session),
serveErrCh: async.NewQueuedChannel[error](1, 1, builder.panicHandler, "server-err-ch"),
serveDoneCh: make(chan struct{}),
serveWG: async.MakeWaitGroup(builder.panicHandler),
inLogger: builder.inLogger,
outLogger: builder.outLogger,
tlsConfig: builder.tlsConfig,
idleBulkTime: builder.idleBulkTime,
storeBuilder: builder.storeBuilder,
cmdExecProfBuilder: builder.cmdExecProfBuilder,
versionInfo: builder.versionInfo,
reporter: builder.reporter,
disableParallelism: builder.disableParallelism,
uidValidityGenerator: builder.uidValidityGenerator,
panicHandler: builder.panicHandler,
}
return s, nil
}