Skip to content

Commit 8f6b250

Browse files
authored
[sessions] Session cleanup (#604)
* Share Intellij run configurations * [sessions] Cleanup inactive sessions after 168h * Create a TTL index on the updatedAt field * Change type of createdAt and updatedAt to Date (required for TTL index) * Regenerated mocks => the session cleanup will only work for sessions create/touch after this change. => older sessions need to dropped manually see: https://www.mongodb.com/docs/manual/core/index-ttl/
1 parent ee3bbe3 commit 8f6b250

File tree

12 files changed

+126
-47
lines changed

12 files changed

+126
-47
lines changed

.run/cluster.run.xml

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<component name="ProjectRunConfigurationManager">
2+
<configuration default="false" name="cluster" type="GoApplicationRunConfiguration" factoryName="Go Application">
3+
<module name="kobs" />
4+
<working_directory value="$PROJECT_DIR$" />
5+
<parameters value="cluster" />
6+
<kind value="PACKAGE" />
7+
<package value="github.com/kobsio/kobs/cmd/kobs" />
8+
<directory value="$PROJECT_DIR$" />
9+
<filePath value="$PROJECT_DIR$/cmd/kobs/main.go" />
10+
<method v="2" />
11+
</configuration>
12+
</component>

.run/hub.run.xml

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<component name="ProjectRunConfigurationManager">
2+
<configuration default="false" name="hub" type="GoApplicationRunConfiguration" factoryName="Go Application">
3+
<module name="kobs" />
4+
<working_directory value="$PROJECT_DIR$" />
5+
<parameters value="hub" />
6+
<kind value="PACKAGE" />
7+
<package value="github.com/kobsio/kobs/cmd/kobs" />
8+
<directory value="$PROJECT_DIR$" />
9+
<filePath value="$PROJECT_DIR$/cmd/kobs/main.go" />
10+
<method v="2" />
11+
</configuration>
12+
</component>

.run/start all.run.xml

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<component name="ProjectRunConfigurationManager">
2+
<configuration default="false" name="start all" type="CompoundRunConfigurationType">
3+
<toRun name="start cluster" type="GoApplicationRunConfiguration" />
4+
<toRun name="hub" type="GoApplicationRunConfiguration" />
5+
<toRun name="start watcher" type="GoApplicationRunConfiguration" />
6+
<method v="2" />
7+
</configuration>
8+
</component>

.run/watcher.run.xml

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<component name="ProjectRunConfigurationManager">
2+
<configuration default="false" name="watcher" type="GoApplicationRunConfiguration" factoryName="Go Application">
3+
<module name="kobs" />
4+
<working_directory value="$PROJECT_DIR$" />
5+
<parameters value="watcher" />
6+
<kind value="PACKAGE" />
7+
<package value="github.com/kobsio/kobs/cmd/kobs" />
8+
<directory value="$PROJECT_DIR$" />
9+
<filePath value="$PROJECT_DIR$/cmd/kobs/main.go" />
10+
<method v="2" />
11+
</configuration>
12+
</component>

CONTRIBUTING.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,11 @@ The frontend lives in the [`plugins/app`](./plugins/app) folder. The shared Reac
165165
- `yarn workspace @kobsio/app build`: Build the React UI.
166166
- `yarn workspace @kobsio/app start`: Start development server for the React UI. The development server is served on port `3000`.
167167

168-
We are using [ESLint](https://eslint.org) and [Prettier](https://prettier.io) for linting and automatic code formation. When you are using [VS Code](https://code.visualstudio.com) you can also use the `launch.json` file from the `.vscode` folder for debugging the React UI.
168+
We are using [ESLint](https://eslint.org) and [Prettier](https://prettier.io) for linting and automatic code formation.
169+
170+
When you are using [VS Code](https://code.visualstudio.com) you can also use the `launch.json` file from the `.vscode` folder for debugging the React UI.
171+
172+
For [Intellj](https://www.jetbrains.com/idea/) users the `.run` folder contains shared run configurations.
169173

170174
#### Plugins
171175

cmd/kobs/hub/hub.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,12 @@ func (r *Cmd) Run(plugins []plugins.Plugin) error {
8383
return err
8484
}
8585

86+
err = dbClient.CreateIndexes(context.Background())
87+
if err != nil {
88+
log.Error(context.Background(), "Could not create indexes", zap.Error(err))
89+
return err
90+
}
91+
8692
pluginsClient, err := hubPlugins.NewClient(plugins, cfg.Hub.Plugins, clustersClient, dbClient)
8793
if err != nil {
8894
log.Error(context.Background(), "Could not create plugins client", zap.Error(err))
@@ -115,7 +121,7 @@ func (r *Cmd) Run(plugins []plugins.Plugin) error {
115121
done := make(chan os.Signal, 1)
116122
signal.Notify(done, os.Interrupt, syscall.SIGTERM)
117123

118-
log.Debug(context.Background(), "Start listining for SIGINT and SIGTERM signal")
124+
log.Debug(context.Background(), "Start listening for SIGINT and SIGTERM signal")
119125
<-done
120126
log.Info(context.Background(), "Shutdown kobs hub...")
121127

pkg/hub/db/db.go

+22
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ type Config struct {
3434
// Client is the interface with all the methods to interact with the db.
3535
type Client interface {
3636
DB() *mongo.Client
37+
CreateIndexes(ctx context.Context) error
3738
SavePlugins(ctx context.Context, cluster string, plugins []plugin.Instance) error
3839
SaveNamespaces(ctx context.Context, cluster string, namespaces []string) error
3940
SaveCRDs(ctx context.Context, crds []kubernetes.CRD) error
@@ -126,6 +127,27 @@ func (c *client) DB() *mongo.Client {
126127
return c.db
127128
}
128129

130+
func (c *client) CreateIndexes(ctx context.Context) error {
131+
ctx, span := c.tracer.Start(ctx, "db.CreateIndexes")
132+
defer span.End()
133+
134+
// Create TTL index for sessions collection, which will delete all inactive sessions which are older than 7 days (168h).
135+
_, err := c.db.Database("kobs").Collection("sessions").Indexes().CreateOne(
136+
ctx,
137+
mongo.IndexModel{
138+
Keys: bson.D{{Key: "updatedAt", Value: 1}},
139+
Options: options.Index().SetExpireAfterSeconds(int32(time.Duration(168 * time.Hour).Seconds())),
140+
})
141+
142+
if err != nil {
143+
span.RecordError(err)
144+
span.SetStatus(codes.Error, err.Error())
145+
return err
146+
}
147+
148+
return nil
149+
}
150+
129151
func (c *client) SavePlugins(ctx context.Context, cluster string, plugins []plugin.Instance) error {
130152
if len(plugins) == 0 {
131153
return nil

pkg/hub/db/db_mock.go

+14
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/hub/db/db_test.go

+9
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@ func TestNewClient(t *testing.T) {
4646
require.NotEmpty(t, c2)
4747
}
4848

49+
func TestCreateIndexes(t *testing.T) {
50+
uri, container := setupDatabase(t)
51+
defer gnomock.Stop(container)
52+
c, _ := NewClient(Config{URI: uri})
53+
54+
err := c.CreateIndexes(context.Background())
55+
require.NoError(t, err)
56+
}
57+
4958
func TestSaveAndGetPlugins(t *testing.T) {
5059
plugins := []plugin.Instance{{
5160
Name: "test-cluster",

pkg/hub/db/sessions.go

+8-7
Original file line numberDiff line numberDiff line change
@@ -15,28 +15,29 @@ import (
1515
)
1616

1717
var (
18-
// ErrSessionNotFound is our custom error which is returned when we are not able to found a session with the
18+
// ErrSessionNotFound is our custom error which is returned when we are not able to find a session with the
1919
// provided session id.
2020
ErrSessionNotFound = fmt.Errorf("session not found")
2121
)
2222

23-
// Session is the structure of a single session as it is saved in the database. Each session contains an id and the a
23+
// Session is the structure of a single session as it is saved in the database. Each session contains an id and a
2424
// user to which the session belongs to. The session also contains a `createdAt` and `updatedAt` field, so that we know
2525
// when a session was created or used the last time.
2626
type Session struct {
2727
ID primitive.ObjectID `json:"id" bson:"_id"`
2828
User authContext.User `json:"user" bson:"user"`
29-
CreatedAt int64 `json:"createdAt" bson:"createdAt"`
30-
UpdatedAt int64 `json:"updatedAt" bson:"updatedAt"`
29+
CreatedAt time.Time `json:"createdAt" bson:"createdAt"`
30+
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"`
3131
}
3232

3333
// CreateSession creates a new session for the provided `user`.
3434
func (c *client) CreateSession(ctx context.Context, user authContext.User) (*Session, error) {
35+
now := time.Now()
3536
session := Session{
3637
ID: primitive.NewObjectID(),
3738
User: user,
38-
CreatedAt: time.Now().Unix(),
39-
UpdatedAt: time.Now().Unix(),
39+
CreatedAt: now,
40+
UpdatedAt: now,
4041
}
4142

4243
ctx, span := c.tracer.Start(ctx, "db.CreateSession")
@@ -86,7 +87,7 @@ func (c *client) GetAndUpdateSession(ctx context.Context, sessionID primitive.Ob
8687
span.SetAttributes(attribute.Key("sessionID").String(sessionID.String()))
8788
defer span.End()
8889

89-
res := c.db.Database("kobs").Collection("sessions").FindOneAndUpdate(ctx, bson.D{{Key: "_id", Value: sessionID}}, bson.D{{Key: "$set", Value: bson.D{{Key: "updatedAt", Value: time.Now().Unix()}}}})
90+
res := c.db.Database("kobs").Collection("sessions").FindOneAndUpdate(ctx, bson.D{{Key: "_id", Value: sessionID}}, bson.D{{Key: "$set", Value: bson.D{{Key: "updatedAt", Value: time.Now()}}}})
9091
if res.Err() != nil {
9192
span.RecordError(res.Err())
9293
span.SetStatus(codes.Error, res.Err().Error())

pkg/plugins/prometheus/instance/instance_mock.go

+13-34
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/plugins/sonarqube/instance/instance_mock.go

+4-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)