Skip to content

Commit d947a84

Browse files
hwbrzzlBowen
andauthored
feat: [#783] Add app.Run(...runner) function to optimize the app running process (#1221)
* feat: [#783] Add bootstrap.Run(...facade) function to optimize the app running process * optimize * optimize * address comments * address comments * add Shutdown * address comments * address comments * chore: update mocks * address comments * remove * address comments --------- Co-authored-by: hwbrzzl <24771476+hwbrzzl@users.noreply.github.com> Co-authored-by: Bowen <hwbrzzl@github.com>
1 parent 70a0c80 commit d947a84

File tree

17 files changed

+770
-88
lines changed

17 files changed

+770
-88
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
.env
21
.idea
32
.DS_Store
43
.vscode

contracts/foundation/application.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ import (
3030
"github.com/goravel/framework/contracts/validation"
3131
)
3232

33+
type Runner interface {
34+
ShouldRun() bool
35+
Run() error
36+
Shutdown() error
37+
}
38+
3339
type AboutItem struct {
3440
Key string
3541
Value string
@@ -42,6 +48,8 @@ type Application interface {
4248
Boot()
4349
// Commands register the given commands with the console application.
4450
Commands([]console.Command)
51+
// Context gets the application context.
52+
Context() context.Context
4553
// GetJson get the JSON implementation.
4654
GetJson() Json
4755
// IsLocale get the current application locale.
@@ -50,10 +58,14 @@ type Application interface {
5058
Publishes(packageName string, paths map[string]string, groups ...string)
5159
// Refresh all modules after changing config, will call the Boot method simultaneously.
5260
Refresh()
61+
// Run runs modules.
62+
Run(runners ...Runner)
5363
// SetJson set the JSON implementation.
5464
SetJson(json Json)
5565
// SetLocale set the current application locale.
5666
SetLocale(ctx context.Context, locale string) context.Context
67+
// Shutdown the application and all its runners.
68+
Shutdown()
5769
// Version gets the version number of the application.
5870
Version() string
5971

contracts/foundation/service_provider.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,15 @@ type ServiceProvider interface {
1010
}
1111

1212
type ServiceProviderWithRelations interface {
13+
ServiceProvider
14+
1315
// Relationship returns the service provider's relationship.
1416
Relationship() binding.Relationship
15-
// Register any application services.
16-
Register(app Application)
17-
// Boot any application services after register.
18-
Boot(app Application)
17+
}
18+
19+
type ServiceProviderWithRunners interface {
20+
ServiceProvider
21+
22+
// Runners returns the service provider's runners.
23+
Runners(app Application) []Runner
1924
}

foundation/.env

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# For testing purposes only.
2+
APP_KEY=12345678901234567890123456789012

foundation/application.go

Lines changed: 125 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ import (
66
"fmt"
77
"maps"
88
"os"
9+
"os/signal"
910
"path/filepath"
1011
"slices"
1112
"sort"
1213
"strings"
14+
"syscall"
1315

1416
"github.com/goravel/framework/config"
1517
frameworkconsole "github.com/goravel/framework/console"
@@ -26,18 +28,19 @@ import (
2628
"github.com/goravel/framework/support/path/internals"
2729
)
2830

29-
var (
30-
App foundation.Application
31-
)
32-
31+
var App foundation.Application
3332
var _ = flag.String("env", support.EnvFilePath, "custom .env path")
3433

3534
func init() {
3635
setEnv()
3736
setRootPath()
3837

38+
ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
39+
3940
app := &Application{
4041
Container: NewContainer(),
42+
ctx: ctx,
43+
cancel: cancel,
4144
publishes: make(map[string]map[string]string),
4245
publishGroups: make(map[string]map[string]string),
4346
}
@@ -50,6 +53,8 @@ func init() {
5053

5154
type Application struct {
5255
*Container
56+
ctx context.Context
57+
cancel context.CancelFunc
5358
configuredServiceProviders []foundation.ServiceProvider
5459
publishes map[string]map[string]string
5560
publishGroups map[string]map[string]string
@@ -61,6 +66,10 @@ func NewApplication() foundation.Application {
6166
return App
6267
}
6368

69+
func (r *Application) About(section string, items []foundation.AboutItem) {
70+
console.AddAboutInformation(section, items...)
71+
}
72+
6473
func (r *Application) Boot() {
6574
r.configuredServiceProviders = r.configuredServiceProviders[:0]
6675
clear(r.publishes)
@@ -87,77 +96,119 @@ func (r *Application) Commands(commands []contractsconsole.Command) {
8796
r.registerCommands(commands)
8897
}
8998

90-
func (r *Application) Path(path ...string) string {
91-
return internals.Path(path...)
99+
func (r *Application) Context() context.Context {
100+
return r.ctx
92101
}
93102

94-
func (r *Application) BasePath(path ...string) string {
95-
return r.absPath(path...)
96-
}
97-
98-
func (r *Application) ConfigPath(path ...string) string {
99-
path = append([]string{support.RelativePath, "config"}, path...)
100-
return r.absPath(path...)
101-
}
102-
103-
func (r *Application) DatabasePath(path ...string) string {
104-
path = append([]string{support.RelativePath, "database"}, path...)
105-
return r.absPath(path...)
106-
}
107-
108-
func (r *Application) ExecutablePath(path ...string) string {
109-
path = append([]string{support.RootPath}, path...)
110-
return r.absPath(path...)
103+
func (r *Application) GetJson() foundation.Json {
104+
return r.json
111105
}
112106

113-
func (r *Application) FacadesPath(path ...string) string {
114-
return internals.FacadesPath(path...)
107+
func (r *Application) IsLocale(ctx context.Context, locale string) bool {
108+
return r.CurrentLocale(ctx) == locale
115109
}
116110

117-
func (r *Application) StoragePath(path ...string) string {
118-
path = append([]string{support.RelativePath, "storage"}, path...)
119-
return r.absPath(path...)
111+
func (r *Application) Publishes(packageName string, paths map[string]string, groups ...string) {
112+
if _, exist := r.publishes[packageName]; !exist {
113+
r.publishes[packageName] = make(map[string]string)
114+
}
115+
maps.Copy(r.publishes[packageName], paths)
116+
for _, group := range groups {
117+
r.addPublishGroup(group, paths)
118+
}
120119
}
121120

122121
func (r *Application) Refresh() {
123122
r.Fresh()
124123
r.Boot()
125124
}
126125

127-
func (r *Application) ResourcePath(path ...string) string {
128-
path = append([]string{support.RelativePath, "resources"}, path...)
129-
return r.absPath(path...)
130-
}
126+
func (r *Application) Run(runners ...foundation.Runner) {
127+
type RunnerWithInfo struct {
128+
name string
129+
runner foundation.Runner
130+
running bool
131+
}
131132

132-
func (r *Application) LangPath(path ...string) string {
133-
defaultPath := "lang"
134-
if configFacade := r.MakeConfig(); configFacade != nil {
135-
defaultPath = configFacade.GetString("app.lang_path", defaultPath)
133+
var allRunners []*RunnerWithInfo
134+
135+
for _, serviceProvider := range r.getConfiguredServiceProviders() {
136+
if serviceProviderWithRunners, ok := serviceProvider.(foundation.ServiceProviderWithRunners); ok {
137+
for _, runner := range serviceProviderWithRunners.Runners(r) {
138+
allRunners = append(allRunners, &RunnerWithInfo{name: fmt.Sprintf("%T", runner), runner: runner, running: false})
139+
}
140+
}
136141
}
137142

138-
path = append([]string{support.RelativePath, defaultPath}, path...)
139-
return r.absPath(path...)
140-
}
143+
for _, runner := range runners {
144+
allRunners = append(allRunners, &RunnerWithInfo{name: fmt.Sprintf("%T", runner), runner: runner, running: false})
145+
}
141146

142-
func (r *Application) PublicPath(path ...string) string {
143-
path = append([]string{support.RelativePath, "public"}, path...)
144-
return r.absPath(path...)
147+
run := func(runner *RunnerWithInfo) {
148+
go func() {
149+
if err := runner.runner.Run(); err != nil {
150+
color.Errorf("%s Run error: %v", runner.name, err)
151+
} else {
152+
runner.running = true
153+
}
154+
}()
155+
156+
go func() {
157+
<-r.ctx.Done()
158+
159+
if !runner.running {
160+
return
161+
}
162+
163+
if err := runner.runner.Shutdown(); err != nil {
164+
color.Errorf("%s Shutdown error: %v", runner.name, err)
165+
}
166+
}()
167+
}
168+
169+
for _, runner := range allRunners {
170+
run(runner)
171+
}
145172
}
146173

147-
func (r *Application) Publishes(packageName string, paths map[string]string, groups ...string) {
148-
if _, exist := r.publishes[packageName]; !exist {
149-
r.publishes[packageName] = make(map[string]string)
174+
func (r *Application) SetJson(j foundation.Json) {
175+
if j != nil {
176+
r.json = j
150177
}
151-
maps.Copy(r.publishes[packageName], paths)
152-
for _, group := range groups {
153-
r.addPublishGroup(group, paths)
178+
}
179+
180+
func (r *Application) SetLocale(ctx context.Context, locale string) context.Context {
181+
lang := r.MakeLang(ctx)
182+
if lang == nil {
183+
color.Errorln("Lang facade not initialized.")
184+
return ctx
154185
}
186+
187+
return lang.SetLocale(locale)
188+
}
189+
190+
func (r *Application) Shutdown() {
191+
r.cancel()
155192
}
156193

157194
func (r *Application) Version() string {
158195
return support.Version
159196
}
160197

198+
func (r *Application) BasePath(path ...string) string {
199+
return r.absPath(path...)
200+
}
201+
202+
func (r *Application) ConfigPath(path ...string) string {
203+
path = append([]string{support.RelativePath, "config"}, path...)
204+
return r.absPath(path...)
205+
}
206+
207+
func (r *Application) DatabasePath(path ...string) string {
208+
path = append([]string{support.RelativePath, "database"}, path...)
209+
return r.absPath(path...)
210+
}
211+
161212
func (r *Application) CurrentLocale(ctx context.Context) string {
162213
lang := r.MakeLang(ctx)
163214
if lang == nil {
@@ -168,32 +219,42 @@ func (r *Application) CurrentLocale(ctx context.Context) string {
168219
return lang.CurrentLocale()
169220
}
170221

171-
func (r *Application) SetLocale(ctx context.Context, locale string) context.Context {
172-
lang := r.MakeLang(ctx)
173-
if lang == nil {
174-
color.Errorln("Lang facade not initialized.")
175-
return ctx
176-
}
222+
func (r *Application) ExecutablePath(path ...string) string {
223+
path = append([]string{support.RootPath}, path...)
224+
return r.absPath(path...)
225+
}
177226

178-
return lang.SetLocale(locale)
227+
func (r *Application) FacadesPath(path ...string) string {
228+
return internals.FacadesPath(path...)
179229
}
180230

181-
func (r *Application) SetJson(j foundation.Json) {
182-
if j != nil {
183-
r.json = j
231+
func (r *Application) LangPath(path ...string) string {
232+
defaultPath := "lang"
233+
if configFacade := r.MakeConfig(); configFacade != nil {
234+
defaultPath = configFacade.GetString("app.lang_path", defaultPath)
184235
}
236+
237+
path = append([]string{support.RelativePath, defaultPath}, path...)
238+
return r.absPath(path...)
185239
}
186240

187-
func (r *Application) GetJson() foundation.Json {
188-
return r.json
241+
func (r *Application) Path(path ...string) string {
242+
return internals.Path(path...)
189243
}
190244

191-
func (r *Application) About(section string, items []foundation.AboutItem) {
192-
console.AddAboutInformation(section, items...)
245+
func (r *Application) PublicPath(path ...string) string {
246+
path = append([]string{support.RelativePath, "public"}, path...)
247+
return r.absPath(path...)
193248
}
194249

195-
func (r *Application) IsLocale(ctx context.Context, locale string) bool {
196-
return r.CurrentLocale(ctx) == locale
250+
func (r *Application) ResourcePath(path ...string) string {
251+
path = append([]string{support.RelativePath, "resources"}, path...)
252+
return r.absPath(path...)
253+
}
254+
255+
func (r *Application) StoragePath(path ...string) string {
256+
path = append([]string{support.RelativePath, "storage"}, path...)
257+
return r.absPath(path...)
197258
}
198259

199260
func (r *Application) absPath(paths ...string) string {

0 commit comments

Comments
 (0)