Skip to content

Commit 9d8c099

Browse files
authored
[#87][#88][#89] bug fixes to turbo and lifecycle. (#90)
* [#87] [#88][#89] bugfixes to turbo and lifecycle. * [#87][88] lifecycle and turbo bug fixes
1 parent 1eeb036 commit 9d8c099

File tree

4 files changed

+90
-64
lines changed

4 files changed

+90
-64
lines changed

lifecycle/component.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ var ErrInvalidComponentState = errors.New("invalid component state")
3131
type Component interface {
3232
// Id is the unique identifier for the component.
3333
Id() string
34-
//OnChange is the function that will be called when the component state changes.
35-
OnChange(prevState, newState ComponentState)
34+
// OnChange is the function that will be called when the component state changes.
35+
// It will be called with the previous state and the new state.
36+
OnChange(f func(prevState, newState ComponentState))
3637
// Start will starting the LifeCycle.
3738
Start() error
3839
// Stop will stop the LifeCycle.
@@ -47,6 +48,8 @@ type ComponentManager interface {
4748
GetState(id string) ComponentState
4849
//List will return a list of all the Components.
4950
List() []Component
51+
// OnChange is the function that will be called when the component state changes.
52+
OnChange(id string, f func(prevState, newState ComponentState))
5053
// Register will register a new Components.
5154
Register(component Component) Component
5255
// StartAll will start all the Components. Returns the number of components started

lifecycle/simple_component.go

+83-55
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ import (
1111

1212
// SimpleComponent is the struct that implements the Component interface.
1313
type SimpleComponent struct {
14+
// stateChangeFuncs
15+
stateChangeFuncs []func(prevState, newState ComponentState)
16+
//mutex
17+
mutex sync.RWMutex
18+
// CompId is the unique identifier for the component.
1419
CompId string
1520
// AfterStart is the function that will be called after the component is started
1621
// The function will be called with the error returned by the StartFunc.
@@ -24,8 +29,6 @@ type SimpleComponent struct {
2429
BeforeStop func()
2530
// CompState is the current state of the component.
2631
CompState ComponentState
27-
// OnStateChange is the function that will be called when the component state changes.
28-
OnStateChange func(prevState, newState ComponentState)
2932
//StartFunc is the function that will be called when the component is started.
3033
// It returns an error if the component failed to start.
3134
StartFunc func() error
@@ -34,15 +37,13 @@ type SimpleComponent struct {
3437
StopFunc func() error
3538
}
3639

37-
// ComponentId is the unique identifier for the component.
38-
func (sc *SimpleComponent) Id() string {
39-
return sc.CompId
40-
}
41-
42-
// OnChange is the function that will be called when the component state changes.
43-
func (sc *SimpleComponent) OnChange(prevState, newState ComponentState) {
44-
if sc.OnStateChange != nil {
45-
sc.OnStateChange(prevState, newState)
40+
// handleStateChange is the function that will be called when the component state changes.
41+
func (sc *SimpleComponent) handleStateChange(prevState, newState ComponentState) {
42+
// if sc.OnStateChange != nil {
43+
// sc.OnStateChange(prevState, newState)
44+
// }
45+
for _, f := range sc.stateChangeFuncs {
46+
f(prevState, newState)
4647
}
4748
if newState == Starting && sc.BeforeStart != nil {
4849
sc.BeforeStart()
@@ -51,10 +52,22 @@ func (sc *SimpleComponent) OnChange(prevState, newState ComponentState) {
5152
}
5253
}
5354

55+
// ComponentId is the unique identifier for the component.
56+
func (sc *SimpleComponent) Id() string {
57+
return sc.CompId
58+
}
59+
60+
// OnChange is the function that will be called when the component state changes.
61+
func (sc *SimpleComponent) OnChange(f func(prevState, newState ComponentState)) {
62+
sc.mutex.Lock()
63+
defer sc.mutex.Unlock()
64+
sc.stateChangeFuncs = append(sc.stateChangeFuncs, f)
65+
}
66+
5467
// Start will starting the LifeCycle.
5568
func (sc *SimpleComponent) Start() (err error) {
5669
if sc.StartFunc != nil {
57-
sc.OnChange(sc.CompState, Starting)
70+
sc.handleStateChange(sc.CompState, Starting)
5871
sc.CompState = Starting
5972
err = sc.StartFunc()
6073
if err != nil {
@@ -63,9 +76,7 @@ func (sc *SimpleComponent) Start() (err error) {
6376
sc.CompState = Running
6477

6578
}
66-
if sc.OnStateChange != nil {
67-
sc.OnStateChange(Starting, sc.CompState)
68-
}
79+
sc.handleStateChange(Starting, sc.CompState)
6980
if sc.AfterStart != nil {
7081
sc.AfterStart(err)
7182
}
@@ -77,17 +88,15 @@ func (sc *SimpleComponent) Start() (err error) {
7788
// Stop will stop the LifeCycle.
7889
func (sc *SimpleComponent) Stop() (err error) {
7990
if sc.StopFunc != nil {
80-
sc.OnChange(sc.CompState, Stopping)
91+
sc.handleStateChange(sc.CompState, Stopping)
8192
sc.CompState = Stopping
8293
err = sc.StopFunc()
8394
if err != nil {
8495
sc.CompState = Error
8596
} else {
8697
sc.CompState = Stopped
8798
}
88-
if sc.OnStateChange != nil {
89-
sc.OnStateChange(Stopping, sc.CompState)
90-
}
99+
sc.handleStateChange(Stopping, sc.CompState)
91100
if sc.AfterStop != nil {
92101
sc.AfterStop(err)
93102

@@ -104,9 +113,10 @@ func (sc *SimpleComponent) State() ComponentState {
104113

105114
// SimpleComponentManager is the struct that manages the component.
106115
type SimpleComponentManager struct {
107-
components map[string]Component
108-
cMutex *sync.RWMutex
109-
waitChan chan struct{}
116+
components map[string]Component
117+
componentIds []string
118+
cMutex *sync.RWMutex
119+
waitChan chan struct{}
110120
}
111121

112122
// GetState will return the current state of the LifeCycle for the component with the given id.
@@ -126,12 +136,22 @@ func (scm *SimpleComponentManager) List() []Component {
126136
defer scm.cMutex.RUnlock()
127137
// Create a slice of Component and iterate over the components map and append the components to the slice.
128138
components := make([]Component, 0, len(scm.components))
129-
for _, component := range scm.components {
130-
components = append(components, component)
139+
for _, compId := range scm.componentIds {
140+
components = append(components, scm.components[compId])
131141
}
132142
return components
133143
}
134144

145+
// OnChange is the function that will be called when the component state changes.
146+
func (scm *SimpleComponentManager) OnChange(id string, f func(prevState, newState ComponentState)) {
147+
scm.cMutex.Lock()
148+
defer scm.cMutex.Unlock()
149+
component, exists := scm.components[id]
150+
if exists {
151+
component.OnChange(f)
152+
}
153+
}
154+
135155
// Register will register a new Components.
136156
// if the component is already registered, get the old component.
137157
func (scm *SimpleComponentManager) Register(component Component) Component {
@@ -141,33 +161,11 @@ func (scm *SimpleComponentManager) Register(component Component) Component {
141161
oldComponent, exists := scm.components[component.Id()]
142162
if !exists {
143163
scm.components[component.Id()] = component
164+
scm.componentIds = append(scm.componentIds, component.Id())
144165
}
145166
return oldComponent
146167
}
147168

148-
// StartAll will start all the Components. Returns the number of components started
149-
func (scm *SimpleComponentManager) StartAll() error {
150-
var err *errutils.MultiError = errutils.NewMultiErr(nil)
151-
for id := range scm.components {
152-
e := scm.Start(id)
153-
if e != nil {
154-
err.Add(e)
155-
}
156-
}
157-
if err.HasErrors() {
158-
return err
159-
} else {
160-
return nil
161-
}
162-
}
163-
164-
// StartAndWait will start all the Components. And will wait for them to be stopped.
165-
func (scm *SimpleComponentManager) StartAndWait() {
166-
scm.StartAll() // Start all the components
167-
scm.Wait() // Wait for all the components to finish
168-
169-
}
170-
171169
// Start will start the LifeCycle for the component with the given id. It returns if the component was started.
172170
func (scm *SimpleComponentManager) Start(id string) (err error) {
173171
scm.cMutex.Lock()
@@ -190,14 +188,38 @@ func (scm *SimpleComponentManager) Start(id string) (err error) {
190188
return ErrCompNotFound
191189
}
192190

191+
// StartAll will start all the Components. Returns the number of components started
192+
func (scm *SimpleComponentManager) StartAll() error {
193+
var err *errutils.MultiError = errutils.NewMultiErr(nil)
194+
for _, id := range scm.componentIds {
195+
e := scm.Start(id)
196+
if e != nil {
197+
err.Add(e)
198+
}
199+
}
200+
if err.HasErrors() {
201+
return err
202+
} else {
203+
return nil
204+
}
205+
}
206+
207+
// StartAndWait will start all the Components. And will wait for them to be stopped.
208+
func (scm *SimpleComponentManager) StartAndWait() {
209+
scm.StartAll() // Start all the components
210+
scm.Wait() // Wait for all the components to finish
211+
212+
}
213+
193214
// StopAll will stop all the Components.
194215
func (scm *SimpleComponentManager) StopAll() error {
195216
logger.InfoF("Stopping all components")
196217
err := errutils.NewMultiErr(nil)
197218
scm.cMutex.Lock()
198219
defer scm.cMutex.Unlock()
199220
wg := &sync.WaitGroup{}
200-
for _, component := range scm.components {
221+
for i := len(scm.componentIds) - 1; i >= 0; i-- {
222+
component := scm.components[scm.componentIds[i]]
201223
if component.State() == Running {
202224
wg.Add(1)
203225
go func(c Component, wg *sync.WaitGroup) {
@@ -257,18 +279,24 @@ func (scm *SimpleComponentManager) Unregister(id string) {
257279
component.Stop()
258280
}
259281
delete(scm.components, id)
282+
for i, compId := range scm.componentIds {
283+
if compId == id {
284+
scm.componentIds = append(scm.componentIds[:i], scm.componentIds[i+1:]...)
285+
break
286+
}
287+
}
260288
}
261289
}
262290

263291
// Wait will wait for all the Components to finish.
264292
func (scm *SimpleComponentManager) Wait() {
265-
go func() {
266-
// Wait for a signal to stop the components.
267-
signalChan := make(chan os.Signal, 1)
268-
signal.Notify(signalChan, syscall.SIGTERM, syscall.SIGINT)
269-
<-signalChan
270-
scm.StopAll()
271-
}()
293+
// go func() {
294+
// // Wait for a signal to stop the components.
295+
// signalChan := make(chan os.Signal, 1)
296+
// signal.Notify(signalChan, syscall.SIGTERM, syscall.SIGINT)
297+
// <-signalChan
298+
// scm.StopAll()
299+
// }()
272300
<-scm.waitChan
273301

274302
}

turbo/turbo.go

+1-6
Original file line numberDiff line numberDiff line change
@@ -438,12 +438,7 @@ func GetPathParamAsBool(id string, r *http.Request) (bool, error) {
438438

439439
// GetQueryParam fetches the query parameters
440440
func GetQueryParam(id string, r *http.Request) (string, error) {
441-
val := r.URL.Query().Get(id)
442-
if val == "" {
443-
logger.ErrorF("Error Fetching Query Param %s", id)
444-
return "err", fmt.Errorf("error fetching query param %s", id)
445-
}
446-
return val, nil
441+
return r.URL.Query().Get(id), nil
447442
}
448443

449444
// GetQueryParamAsInt fetches the int query parameters

turbo/turbo_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ func TestRouter_GetQueryParams(t *testing.T) {
460460
id: "test3",
461461
r: &http.Request{URL: strUrl},
462462
},
463-
want: "err",
463+
want: "",
464464
},
465465
}
466466
for _, tt := range tests {

0 commit comments

Comments
 (0)