-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
initial commit, migrating from gravestench/runtime-examples, updating…
… to use the new implementation gravestench/servicemesh
- Loading branch information
0 parents
commit c716312
Showing
94 changed files
with
4,254 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
.idea | ||
go.sum |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
## About | ||
|
||
go see https://github.com/gravestench/runtime | ||
|
||
There are example runtime services in the `services` directory. Some of | ||
these services depend on each other, namely the config file manager. | ||
|
||
There are example build targets in the `cmd` directory. There may be one-off | ||
service declarations inside of these directories. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package main | ||
|
||
type example struct { | ||
name string | ||
} | ||
|
||
func (e *example) Init(r servicemesh.R) { | ||
return | ||
} | ||
|
||
func (e *example) Name() string { | ||
return e.name | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package main | ||
|
||
func main() { | ||
rt := servicemesh.New("my runtime") | ||
|
||
rt.Add(&example{name: "foo"}) | ||
|
||
rt.Run() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
package main | ||
|
||
import ( | ||
"sync" | ||
"time" | ||
|
||
tea "github.com/charmbracelet/bubbletea" | ||
"github.com/gravestench/runtime/pkg/events" | ||
) | ||
|
||
type serviceWithModel interface { | ||
Model() tea.Model | ||
} | ||
|
||
type bubbleteaService struct { | ||
*tea.Program | ||
mux sync.Mutex | ||
} | ||
|
||
func (b *bubbleteaService) Init(mesh servicemesh.M) { | ||
go b.runLoop() | ||
|
||
b.bindExisting(rt) | ||
|
||
rt.Events().On(events.EventServiceAdded, func(...any) { | ||
b.bindExisting(rt) | ||
}) | ||
} | ||
|
||
func (b *bubbleteaService) runLoop() { | ||
for { | ||
time.Sleep(time.Second) | ||
|
||
if b.Program == nil { | ||
continue | ||
} | ||
|
||
b.Program.Run() | ||
} | ||
} | ||
|
||
func (b *bubbleteaService) bindExisting(mesh servicemesh.M) { | ||
var models []tea.Model | ||
|
||
for _, service := range rt.Services() { | ||
if candidate, ok := service.(serviceWithModel); ok { | ||
models = append(models, candidate.Model()) | ||
} | ||
} | ||
|
||
if len(models) < 1 { | ||
return | ||
} | ||
|
||
if b.Program != nil { | ||
b.Program.Kill() | ||
} | ||
|
||
b.Program = tea.NewProgram(b.newMainModel(models)) | ||
} | ||
|
||
func (b *bubbleteaService) newMainModel(models []tea.Model) tea.Model { | ||
return &mainModel{models: models} | ||
} | ||
|
||
func (b *bubbleteaService) Name() string { | ||
return "Bubbletea" | ||
} | ||
|
||
type mainModel struct { | ||
models []tea.Model | ||
currentModelIndex int | ||
} | ||
|
||
func (m mainModel) Init() (cmd tea.Cmd) { | ||
for _, model := range m.models { | ||
cmd = model.Init() | ||
} | ||
|
||
return cmd | ||
} | ||
|
||
func (m mainModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { | ||
if len(m.models) < 1 { | ||
return m, nil | ||
} | ||
|
||
if m.currentModelIndex < 0 || m.currentModelIndex >= len(m.models) { | ||
m.currentModelIndex = 0 | ||
} | ||
|
||
return m.models[m.currentModelIndex].Update(msg) | ||
} | ||
|
||
func (m mainModel) View() string { | ||
if len(m.models) < 1 { | ||
return "" | ||
} | ||
|
||
if m.currentModelIndex < 0 || m.currentModelIndex >= len(m.models) { | ||
m.currentModelIndex = 0 | ||
} | ||
|
||
return m.models[m.currentModelIndex].View() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
package main | ||
|
||
import ( | ||
"errors" | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
"time" | ||
|
||
"github.com/charmbracelet/bubbles/filepicker" | ||
tea "github.com/charmbracelet/bubbletea" | ||
) | ||
|
||
type filePickerService struct { | ||
model *filePickerModel | ||
} | ||
|
||
func (t *filePickerService) Init(mesh servicemesh.M) { | ||
t.model = &filePickerModel{} | ||
} | ||
|
||
func (t *filePickerService) Name() string { | ||
return "Filepicker TUI" | ||
} | ||
|
||
func (t *filePickerService) Model() tea.Model { | ||
return t.model | ||
} | ||
|
||
type filePickerModel struct { | ||
filepicker filepicker.Model | ||
selectedFile string | ||
quitting bool | ||
err error | ||
} | ||
|
||
type clearErrorMsg struct{} | ||
|
||
func clearErrorAfter(t time.Duration) tea.Cmd { | ||
return tea.Tick(t, func(_ time.Time) tea.Msg { | ||
return clearErrorMsg{} | ||
}) | ||
} | ||
|
||
func (m filePickerModel) Init() tea.Cmd { | ||
m.filepicker.CurrentDirectory, _ = os.UserHomeDir() | ||
m.filepicker.CurrentDirectory = filepath.Join(m.filepicker.CurrentDirectory, "Downloads") | ||
return m.filepicker.Init() | ||
} | ||
|
||
func (m filePickerModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { | ||
switch msg := msg.(type) { | ||
case tea.KeyMsg: | ||
switch msg.String() { | ||
case "ctrl+c", "q": | ||
m.quitting = true | ||
return m, tea.Quit | ||
} | ||
case clearErrorMsg: | ||
m.err = nil | ||
} | ||
|
||
var cmd tea.Cmd | ||
m.filepicker, cmd = m.filepicker.Update(msg) | ||
|
||
// Did the user select a file? | ||
if didSelect, path := m.filepicker.DidSelectFile(msg); didSelect { | ||
// Get the path of the selected file. | ||
m.selectedFile = path | ||
} | ||
|
||
// Did the user select a disabled file? | ||
// This is only necessary to display an error to the user. | ||
if didSelect, path := m.filepicker.DidSelectDisabledFile(msg); didSelect { | ||
// Let's clear the selectedFile and display an error. | ||
m.err = errors.New(path + " is not valid.") | ||
m.selectedFile = "" | ||
return m, tea.Batch(cmd, clearErrorAfter(2*time.Second)) | ||
} | ||
|
||
return m, cmd | ||
} | ||
|
||
func (m filePickerModel) View() string { | ||
if m.quitting { | ||
return "" | ||
} | ||
var s strings.Builder | ||
s.WriteString("\n ") | ||
if m.err != nil { | ||
s.WriteString(m.filepicker.Styles.DisabledFile.Render(m.err.Error())) | ||
} else if m.selectedFile == "" { | ||
s.WriteString("Pick a file:") | ||
} else { | ||
s.WriteString("Selected file: " + m.filepicker.Styles.Selected.Render(m.selectedFile)) | ||
} | ||
s.WriteString("\n\n" + m.filepicker.View() + "\n") | ||
return s.String() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package main | ||
|
||
import ( | ||
"os" | ||
) | ||
|
||
func main() { | ||
rt := servicemesh.New() | ||
|
||
logFile, err := os.OpenFile("/tmp/log.out", os.O_RDWR|os.O_CREATE, 0644) | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
rt.SetLogDestination(logFile) | ||
|
||
rt.Add(&bubbleteaService{}) | ||
rt.Add(&filePickerService{}) | ||
|
||
rt.Run() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package main | ||
|
||
import ( | ||
"github.com/gravestench/servicesmesh-examples/services/config_file" | ||
) | ||
|
||
func main() { | ||
rt := servicemesh.New() | ||
cfgManager := &config_file.Service{} | ||
|
||
rt.Add(cfgManager) | ||
|
||
// This service has a dependency on the config manager | ||
rt.Add(&serviceThatUsesConfigManager{}) | ||
|
||
rt.Run() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package main | ||
|
||
import ( | ||
"github.com/gravestench/servicesmesh-examples/services/config_file" | ||
) | ||
|
||
var _ interface { | ||
servicemesh.S | ||
servicemesh.HasLogger | ||
servicemesh.HasDependencies | ||
} = &serviceThatUsesConfigManager{} | ||
|
||
type serviceThatUsesConfigManager struct { | ||
configManager config_file.Manager // dependency on config file manager | ||
log *slog.Logger | ||
} | ||
|
||
func (s *serviceThatUsesConfigManager) ResolveDependencies(mesh servicemesh.M) { | ||
for _, service := range rt.Services() { | ||
if instance, ok := service.(config_file.Manager); ok { | ||
s.configManager = instance | ||
} | ||
} | ||
} | ||
|
||
func (s *serviceThatUsesConfigManager) DependenciesResolved() bool { | ||
return s.configManager != nil | ||
} | ||
|
||
func (s *serviceThatUsesConfigManager) Init(r servicemesh.R) { | ||
cfg, err := s.configManager.GetConfig("test.json") | ||
if err != nil { | ||
s.log.Fatal().Msgf("couldnt load example config file", "error", err) | ||
} | ||
|
||
group := cfg.Group("foo") | ||
|
||
group.Set("a", 1) | ||
group.Set("b", 2) | ||
group.Set("c", 3) | ||
|
||
s.configManager.SaveConfig("test.json") | ||
} | ||
|
||
func (s *serviceThatUsesConfigManager) Name() string { | ||
return "Config User" | ||
} | ||
|
||
func (s *serviceThatUsesConfigManager) SetLogger(logger *slog.Logger) { | ||
s.log = logger | ||
} | ||
|
||
func (s *serviceThatUsesConfigManager) Logger() *slog.Logger { | ||
return s.log | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package main | ||
|
||
func main() { | ||
rt := servicemesh.New() | ||
|
||
// each service has a dependency that is not | ||
// actually resolved through the runtime but by | ||
// some other means (that part is up to you). | ||
rt.Add(newServiceWithAsyncDependencyResolution()) | ||
rt.Add(newServiceWithAsyncDependencyResolution()) | ||
rt.Add(newServiceWithAsyncDependencyResolution()) | ||
rt.Add(newServiceWithAsyncDependencyResolution()) | ||
rt.Add(newServiceWithAsyncDependencyResolution()) | ||
|
||
rt.Run() | ||
} |
Oops, something went wrong.