Skip to content

Commit

Permalink
feat: remove On prefix from service API Tick, Tock
Browse files Browse the repository at this point in the history
Signed-off-by: Marko Kungla <[email protected]>
  • Loading branch information
mkungla committed Jan 30, 2024
1 parent 6e46b20 commit 764f2e5
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 77 deletions.
116 changes: 45 additions & 71 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,21 @@ Happy SDK is designed to simplify your development process without introducing a
package main

import (
"errors"
"github.com/happy-sdk/happy"
"fmt"

"github.com/happy-sdk/happy"
"github.com/happy-sdk/happy/sdk/logging"
)

func main() {
app := happy.New()
app.Do(func(sess *happy.Session, args happy.Args) error {
sess.Log().Println("Hello, world!")
return errors.New("This is just a basic example.")
})
app.Main()
func ExampleNew() {
app := happy.New(happy.Settings{})
app.Do(func(sess *happy.Session, args happy.Args) error {
sess.Log().Println("Hello, world!")
return nil
})
app.Run()
}

```

For more examples, take a look at the [examples](#examples) section and the examples in the ./examples/ directory."
Expand All @@ -40,22 +43,26 @@ For more examples, take a look at the [examples](#examples) section and the exam
More details of api read happy Godoc

```go
...
app.WithAddon(/* adds addon to app */)
app.WithMigrations(/* use migration manager */)
app.WithService(/* adds service to app */)
app.WithCommand(/* adds command to app */)
app.WithFlag(/* adds flag to app root command*/)
app.WithLogger(/* uses provided logger */)
app.WithOptions(/* adds allowed runtime option */)
...

...
// All the following are optional
app.Before(/* called always before any command is invoked*/)
app.BeforeAlways(/* called always before any command is invoked*/)
app.Before(/* called before root command is invoked*/)
app.Do(/* root command Do function */)
app.AfterSuccess(/* called when root cmd or sub command returns without errors */)
app.AfterFailure(/* called when root cmd or sub command returns with errors */)
app.AfterAlways(/* called always when root cmd or sub command returns */)
app.OnTick(/* called while root command is blocking */)
app.OnTock(/* called while root command is blocking after tick*/)
app.OnInstall(/* optional installation step to call when user first uses your app */)
app.OnMigrate(/* optional migrations step to call when user upgrades/downgrades app */)
app.Cron(/* optional cron jobs registered for application */)
app.RegisterService(/* register standalone service to your app. */)
app.AddCommand(/* add sub command to your app. */)
app.AddFlag(/* add global flag to your app. */)
app.Setting(/* add additional, custom user settings to your app */)
app.Tick(/* called in specific interfal while root command is blocking */)
app.Tock(/* called after every tick*/)
...
```

Expand All @@ -69,19 +76,24 @@ app.Setting(/* add additional, custom user settings to your app */)
cmd := happy.NewCommand(
"my-command",
happy.Option("usage", "My sub-command"),
happy.Option("argn.min", 1),
happy.Option("argn.max", 10),
)

cmd.Do(/* Main function for the command */)

// Optional:
cmd.AddInfo(/* add long description paragraph for command*/)
cmd.AddFlag(/* add flag to command*/)

cmd.Before(/* Called after app.Before and before cmd.Do */)
cmd.AfterSuccess(/* Called when cmd.Do returns without errors */)
cmd.AfterFailure(/* Called when cmd.Do returns with errors */)
cmd.AfterAlways(/* Called always when cmd.Do returns */)
cmd.AddSubCommand(/* Add a sub-command to the command */)
cmd.AddFlag(/* Add a flag for the command */)

app.AddCommand(cmd)
cmd.AddSubCommand(/* add subcommand to command */)
...
```

Expand All @@ -91,19 +103,16 @@ The `happy.Service` API provides a flexible way to add runtime-controllable back

```go
...
svc := happy.NewService(
"my-service",
happy.Option("usage", "my custom service"),
)
svc := happy.NewService("my-service")

svc.OnInitialize(/* Called when the app starts. */)
svc.OnStart(/* Called when the service is requested to start. */)
svc.OnStop(/* Called when the service is requested to stop. */)
svc.OnEvent(/* Called when a specific event is received. */)
svc.OnAnyEvent(/* Called when any event is received. */)
svc.Cron(/* Scheduled cron jobs to run when the service is running. */)
svc.OnTick(/* Called every tick when the service is running. */)
svc.OnTock(/* Called after every tick when the service is running. */)
svc.Tick(/* Called every tick when the service is running. */)
svc.Tock(/* Called after every tick when the service is running. */)

app.RegisterService(svc)
...
Expand Down Expand Up @@ -136,6 +145,10 @@ package helloworld

import "github.com/happy-sdk/happy"

type HelloWorldAPI struct {
happy.API
}

func Addon() *happy.Addon {
addon := happy.NewAddon(
"hello-world",
Expand All @@ -152,11 +165,14 @@ func Addon() *happy.Addon {
addon.ProvidesService(...)

// Optional: Make a custom API accessible across the application
addon.API = &HelloWorldAPI{}
addon.ProvidesAPI(&HelloWorldAPI{})

// Register all events that the addon may emit
// Register all events that the addon may emit ()
addon.Emits("event scope", "event key" , "event description", /* example payload */)
addon.EmitsEvent(/* if you already have event */)

addon.Option("key", "value", "addon specific runtime option", /* optional validator*/)

// Optional callback to be called when the addon is registered
addon.OnRegister(func(sess *happy.Session, opts *happy.Options) error {
sess.Log().Notice("hello-world addon registered")
Expand All @@ -167,51 +183,9 @@ func Addon() *happy.Addon {
}
```

## examples

**hello**

*most minimal usage*

```
go run ./examples/hello/
go run ./examples/hello/ nickname
# increase verbosity
go run ./examples/hello/ --debug
go run ./examples/hello/ --system-debug
# help
go run ./examples/hello/ -h
```

**kitchensink**

*main application when no subcommand is provided*

```
go run ./examples/kitchensink/
# increase verbosity
go run ./examples/kitchensink/ --verbose
go run ./examples/kitchensink/ --debug
go run ./examples/kitchensink/ --system-debug
# main application help
go run ./examples/kitchensink/ -h
```

*hello command with flags*

```
go run ./examples/kitchensink/ hello --name me --repeat 10
# or shorter
go run ./examples/kitchensink/ hello -n me -r 10
# help for hello command
go run ./examples/kitchensink/ hello -h
```

## Credits

[![GitHub contributors](https://img.shields.io/github/contributors/mkungla/happy?style=flat-square)](https://github.com/happy-sdk/happy/graphs/contributors)
[![GitHub contributors](https://img.shields.io/github/contributors/happy-sdk/happy?style=flat-square)](https://github.com/happy-sdk/happy/graphs/contributors)

<sub>**Happy banner design.**</sub>
<sup>Happy banner was designed by Egon Elbre <a href="https://egonelbre.com/" target="_blank">egonelbre.com</a></sup>
12 changes: 9 additions & 3 deletions example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,23 @@
package happy_test

import (
"fmt"

"github.com/happy-sdk/happy"
"github.com/happy-sdk/happy/sdk/logging"
)

func ExampleNew() {
app := happy.New(happy.Settings{})
log := logging.NewTestLogger(logging.LevelError)

app := happy.New(happy.Settings{})
app.WithLogger(log)
app.Do(func(sess *happy.Session, args happy.Args) error {
sess.Log().Println("Hello, world!")
return nil
})
// app.Run()

app.Run()
fmt.Println(log.Output())
// Output:
// {"level":"out","msg":"Hello, world!"}
}
98 changes: 97 additions & 1 deletion happy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,100 @@
//
// Copyright © 2022 The Happy Authors

package happy
package happy_test

import (
"fmt"
"os"
"testing"
"time"

"github.com/happy-sdk/happy"
"github.com/happy-sdk/happy/pkg/devel/testutils"
"github.com/happy-sdk/happy/sdk/logging"
)

func TestDefaultSettings(t *testing.T) {
log := logging.NewTestLogger(logging.LevelError)

app := happy.New(happy.Settings{})
app.WithLogger(log)
app.Do(func(sess *happy.Session, args happy.Args) error {
testutils.Equal(t, "", sess.Get("app.copyright.by").String(), "app.copyright.by")
testutils.Equal(t, time.Now().Year(), sess.Get("app.copyright.since").Int(), "app.copyright.since")
testutils.Equal(t, "Local", sess.Get("app.datetime.location").String(), "app.datetime.location")
testutils.Equal(t, "", sess.Get("app.description").String(), "app.description")
testutils.Equal(t, "", sess.Get("app.license").String(), "app.license")
testutils.Equal(t, "0", sess.Get("app.main.argn.max").String(), "app.main.argn.max")
testutils.Equal(t, "Happy Prototype", sess.Get("app.name").String(), "app.name")

testutils.Equal(t, "30s", sess.Get("app.service.loader.timeout").String(), "app.service.loader.timeout")
testutils.Equal(t, time.Second*30, sess.Get("app.service.loader.timeout").Duration(), "app.service.loader.timeout")

testutils.Equal(t, "1s", sess.Get("app.throttle.ticks").String(), "app.throttle.ticks")
testutils.Equal(t, time.Second*1, sess.Get("app.throttle.ticks").Duration(), "app.throttle.ticks")

testutils.Equal(t, "1", sess.Get("instance.max").String(), "instance.max")
testutils.Equal(t, 1, sess.Get("instance.max").Int(), "instance.max")

testutils.Equal(t, "com.github.happysdk.happy-test", sess.Get("app.slug").String(), "app.slug")

return nil
})

app.Run()
}

func TestDefaultConfig(t *testing.T) {
log := logging.NewTestLogger(logging.LevelError)

app := happy.New(happy.Settings{})
app.WithLogger(log)
app.Do(func(sess *happy.Session, args happy.Args) error {
testutils.Equal(t, 13, sess.Config().Len(), "default runtime config should be empty")
host, err := os.Hostname()
if err != nil {
return err
}
addr := fmt.Sprintf("happy://%s/com.github.happysdk.happy-test", host)
testutils.Equal(t, addr, sess.Get("app.address").String(), "app.address")
testutils.Equal(t, true, sess.Get("app.devel").Bool(), "app.devel")
testutils.Equal(t, true, sess.Get("app.firstuse").Bool(), "app.firstuse")
testutils.Equal(t, false, sess.Get("app.main.exec.x").Bool(), "app.main.exec.x")
testutils.Equal(t, "default-devel", sess.Get("app.profile.name").String(), "app.profile.name")
testutils.Equal(t, "v1.0.0-0xDEV", sess.Get("app.version").String(), "app.version")

tmpdir := sess.Get("app.fs.path.tmp").String()
testutils.HasPrefix(t, tmpdir, os.TempDir(), "app.fs.path.tmp")

wd, err := os.Getwd()
if err != nil {
return err
}
testutils.Equal(t, wd, sess.Get("app.fs.path.pwd").String(), "app.fs.path.pwd")

home, err := os.UserHomeDir()
if err != nil {
return err
}
testutils.Equal(t, home, sess.Get("app.fs.path.home").String(), "app.fs.path.home")

testutils.Equal(t, fmt.Sprintf("%s/config/com.github.happysdk.happy-test/profiles/default-devel", tmpdir), sess.Get("app.fs.path.config").String(), "app.fs.path.config")
testutils.Equal(t, fmt.Sprintf("%s/cache/com.github.happysdk.happy-test/profiles/default-devel", tmpdir), sess.Get("app.fs.path.cache").String(), "app.fs.path.cache")
testutils.Equal(t, fmt.Sprintf("%s/config/com.github.happysdk.happy-test/profiles/default-devel/profile.preferences", tmpdir), sess.Get("app.profile.file").String(), "app.profile.file")
return nil
})
app.Run()
}

func TestDefaultOptions(t *testing.T) {
log := logging.NewTestLogger(logging.LevelError)

app := happy.New(happy.Settings{})
app.WithLogger(log)
app.Do(func(sess *happy.Session, args happy.Args) error {
testutils.Equal(t, 0, sess.Opts().Len(), "default runtime opts should be empty")
return nil
})
app.Run()
}
4 changes: 2 additions & 2 deletions service.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,12 @@ func (s *Service) OnStop(action Action) {
}

// OnTick when set will be called every application tick when service is in running state.
func (s *Service) OnTick(action ActionTick) {
func (s *Service) Tick(action ActionTick) {
s.tickAction = action
}

// OnTock is called after every tick.
func (s *Service) OnTock(action ActionTock) {
func (s *Service) Tock(action ActionTock) {
s.tockAction = action
}

Expand Down

0 comments on commit 764f2e5

Please sign in to comment.