Skip to content

Commit

Permalink
feat: blocking strategy
Browse files Browse the repository at this point in the history
  • Loading branch information
pirosiki197 committed Nov 2, 2024
1 parent b550844 commit 08b9ad4
Show file tree
Hide file tree
Showing 15 changed files with 1,595 additions and 1,332 deletions.
2 changes: 2 additions & 0 deletions .local-dev/config/ns.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ components:
enable: true
url: http://sablier.sablier.svc.cluster.local
sessionDuration: 5m
blocking:
timeout: 1m
tls:
type: traefik
traefik:
Expand Down
12 changes: 11 additions & 1 deletion api/proto/neoshowcase/protobuf/gateway.proto
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,22 @@ enum DeployType {
STATIC = 1;
}

message AutoShutdownConfig {
enum StartupBehavior {
UNDEFINED = 0;
LOADING_PAGE = 1;
BLOCKING = 2;
}
bool enabled = 1;
StartupBehavior startup = 2;
}

message RuntimeConfig {
bool use_mariadb = 1;
bool use_mongodb = 2;
string entrypoint = 3;
string command = 4;
bool auto_shutdown = 5;
AutoShutdownConfig auto_shutdown = 5;
}

message BuildConfigRuntimeBuildpack {
Expand Down
3 changes: 2 additions & 1 deletion docs/dbschema/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
| Name | Columns | Comment | Type |
| ---- | ------- | ------- | ---- |
| [applications](applications.md) | 12 | アプリケーションテーブル | BASE TABLE |
| [application_config](application_config.md) | 13 | アプリケーション詳細設定テーブル | BASE TABLE |
| [application_config](application_config.md) | 14 | アプリケーション詳細設定テーブル | BASE TABLE |
| [application_owners](application_owners.md) | 2 | アプリケーション所有者テーブル | BASE TABLE |
| [artifacts](artifacts.md) | 6 | 静的ファイル生成物テーブル | BASE TABLE |
| [builds](builds.md) | 10 | ビルドテーブル | BASE TABLE |
Expand Down Expand Up @@ -59,6 +59,7 @@ erDiagram
tinyint_1_ use_mariadb
tinyint_1_ use_mongodb
tinyint_1_ auto_shutdown
enum__undefined___loading-page___blocking__ startup_behavior
enum__runtime-buildpack___runtime-cmd___runtime-dockerfile___static-buildpack___static-cmd___static-dockerfile__ build_type
varchar_1000_ base_image
text build_cmd
Expand Down
3 changes: 3 additions & 0 deletions docs/dbschema/application_config.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ CREATE TABLE `application_config` (
`use_mariadb` tinyint(1) NOT NULL COMMENT 'MariaDBを使用するか',
`use_mongodb` tinyint(1) NOT NULL COMMENT 'MongoDBを使用するか',
`auto_shutdown` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'アプリケーションの自動シャットダウン',
`startup_behavior` enum('undefined','loading-page','blocking') NOT NULL COMMENT 'アプリ起動時の振る舞い',
`build_type` enum('runtime-buildpack','runtime-cmd','runtime-dockerfile','static-buildpack','static-cmd','static-dockerfile') NOT NULL COMMENT 'ビルドタイプ',
`base_image` varchar(1000) NOT NULL COMMENT 'ベースイメージの名前',
`build_cmd` text NOT NULL COMMENT 'ビルドコマンド',
Expand All @@ -37,6 +38,7 @@ CREATE TABLE `application_config` (
| use_mariadb | tinyint(1) | | false | | | MariaDBを使用するか |
| use_mongodb | tinyint(1) | | false | | | MongoDBを使用するか |
| auto_shutdown | tinyint(1) | 0 | false | | | アプリケーションの自動シャットダウン |
| startup_behavior | enum('undefined','loading-page','blocking') | | false | | | アプリ起動時の振る舞い |
| build_type | enum('runtime-buildpack','runtime-cmd','runtime-dockerfile','static-buildpack','static-cmd','static-dockerfile') | | false | | | ビルドタイプ |
| base_image | varchar(1000) | | false | | | ベースイメージの名前 |
| build_cmd | text | | false | | | ビルドコマンド |
Expand Down Expand Up @@ -72,6 +74,7 @@ erDiagram
tinyint_1_ use_mariadb
tinyint_1_ use_mongodb
tinyint_1_ auto_shutdown
enum__undefined___loading-page___blocking__ startup_behavior
enum__runtime-buildpack___runtime-cmd___runtime-dockerfile___static-buildpack___static-cmd___static-dockerfile__ build_type
varchar_1000_ base_image
text build_cmd
Expand Down
1 change: 1 addition & 0 deletions docs/dbschema/applications.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ erDiagram
tinyint_1_ use_mariadb
tinyint_1_ use_mongodb
tinyint_1_ auto_shutdown
enum__undefined___loading-page___blocking__ startup_behavior
enum__runtime-buildpack___runtime-cmd___runtime-dockerfile___static-buildpack___static-cmd___static-dockerfile__ build_type
varchar_1000_ base_image
text build_cmd
Expand Down
5 changes: 5 additions & 0 deletions migrations/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ CREATE TABLE `application_config`
`use_mariadb` TINYINT(1) NOT NULL COMMENT 'MariaDBを使用するか',
`use_mongodb` TINYINT(1) NOT NULL COMMENT 'MongoDBを使用するか',
`auto_shutdown` TINYINT(1) NOT NULL DEFAULT 0 COMMENT 'アプリケーションの自動シャットダウン',
`startup_behavior` ENUM (
'undefined',
'loading-page',
'blocking'
) NOT NULL COMMENT 'アプリ起動時の振る舞い',
`build_type` ENUM (
'runtime-buildpack',
'runtime-cmd',
Expand Down
25 changes: 24 additions & 1 deletion pkg/domain/app_build_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,29 @@ type RuntimeConfig struct {
UseMongoDB bool
Entrypoint string
Command string
AutoShutdown bool
AutoShutdown AutoShutdownConfig
}

type AutoShutdownConfig struct {
Enabled bool
// Startup must be set if Enabled is true.
Startup StartupBehavior
}

// StartupBehavior represents the behavior of the application when it starts up.
// This is used to determine how to handle the request until the application is ready.
type StartupBehavior int

const (
StartupBehaviorUndefined StartupBehavior = iota
// StartupBehaviorLoadingPage is a strategy that shows a loading page until the application is ready.
// This is suitable for web applications that are accessed from frontend.
StartupBehaviorLoadingPage
// StartupBehaviorBlocking is a strategy that blocks the request until the application is ready.
// This is suitable for API servers.
StartupBehaviorBlocking
)

const shellSpecialCharacters = "`" + `~#$&*()\|[]{};'"<>?!=`

func ParseArgs(s string) ([]string, error) {
Expand All @@ -65,6 +85,9 @@ func (rc *RuntimeConfig) Validate() error {
if _, err := ParseArgs(rc.Command); err != nil {
return errors.Wrap(err, "command")
}
if rc.AutoShutdown.Enabled && rc.AutoShutdown.Startup == StartupBehaviorUndefined {
return errors.New("startup is required if auto shutdown is enabled")
}
return nil
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/infrastructure/backend/k8simpl/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ func sablierMiddlewareName(appID string) string {
}

func (b *Backend) useSablier(app *domain.Application) bool {
return app.DeployType == domain.DeployTypeRuntime && app.Config.BuildConfig.GetRuntimeConfig().AutoShutdown
return app.DeployType == domain.DeployTypeRuntime && app.Config.BuildConfig.GetRuntimeConfig().AutoShutdown.Enabled
}

func sablierGroupName(appID string) string {
Expand Down
4 changes: 4 additions & 0 deletions pkg/infrastructure/backend/k8simpl/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,10 @@ type Config struct {
//
// Example: "10m"
SessionDuration string `mapstructure:"sessionDuration" yaml:"sessionDuration"`
Blocking struct {
// Timeout defines how long the blocking should last.
Timeout string `mapstructure:"timeout" yaml:"blockingTimeout"`
} `mapstructure:"blocking" yaml:"blocking"`
} `mapstructure:"sablier" yaml:"sablier"`
}
// TLS section defines tls setting for user app ingress.
Expand Down
46 changes: 33 additions & 13 deletions pkg/infrastructure/backend/k8simpl/ingress.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,28 +64,48 @@ func (b *Backend) certificate(targetDomain string) *certmanagerv1.Certificate {
}
}

func (b *Backend) sablierMiddleware(app *domain.Application) *traefikv1alpha1.Middleware {
func (b *Backend) jsonSablierConfig(app *domain.Application) []byte {
type DynamicConfig = struct {
DisplayName string `json:"displayName"`
ShowDetails string `json:"showDetails"`
Theme string `json:"theme"`
}
config := struct {
SablierURL string `json:"sablierURL"`
Group string `json:"group"`
SessionDuration string `json:"sessionDuration"`
Dynamic DynamicConfig `json:"dynamic"`
}{
b.config.Middleware.Sablier.SablierURL,
sablierGroupName(app.ID),
b.config.Middleware.Sablier.SessionDuration,
DynamicConfig{
type BlockingConfig = struct {
Timeout string `json:"timeout"`
}
type SablierConfig = struct {
SablierURL string `json:"sablierURL"`
Group string `json:"group"`
SessionDuration string `json:"sessionDuration"`
Dynamic *DynamicConfig `json:"dynamic,omitempty"`
Blocking *BlockingConfig `json:"blocking,omitempty"`
}

config := SablierConfig{
SablierURL: b.config.Middleware.Sablier.SablierURL,
Group: sablierGroupName(app.ID),
SessionDuration: b.config.Middleware.Sablier.SessionDuration,
}

switch app.Config.BuildConfig.GetRuntimeConfig().AutoShutdown.Startup {
case domain.StartupBehaviorLoadingPage:
config.Dynamic = &DynamicConfig{
DisplayName: app.Name,
ShowDetails: "true",
Theme: "ghost",
},
}
case domain.StartupBehaviorBlocking:
config.Blocking = &BlockingConfig{
Timeout: b.config.Middleware.Sablier.Blocking.Timeout,
}
}

data, _ := json.Marshal(config)
return data
}

func (b *Backend) sablierMiddleware(app *domain.Application) *traefikv1alpha1.Middleware {
configData := b.jsonSablierConfig(app)
return &traefikv1alpha1.Middleware{
TypeMeta: metav1.TypeMeta{
Kind: "Middleware",
Expand All @@ -98,7 +118,7 @@ func (b *Backend) sablierMiddleware(app *domain.Application) *traefikv1alpha1.Mi
},
Spec: traefikv1alpha1.MiddlewareSpec{
Plugin: map[string]v1.JSON{
"sablier": {Raw: data},
"sablier": {Raw: configData},
},
},
}
Expand Down
Loading

0 comments on commit 08b9ad4

Please sign in to comment.