123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- package lifecycle
- import (
- "context"
- "fmt"
- "log"
- "log/slog"
- "os"
- "os/signal"
- "syscall"
- "github.com/ollama/ollama/app/store"
- "github.com/ollama/ollama/app/tray"
- )
- func Run() {
- InitLogging()
- ctx, cancel := context.WithCancel(context.Background())
- var done chan int
- t, err := tray.NewTray()
- if err != nil {
- log.Fatalf("Failed to start: %s", err)
- }
- callbacks := t.GetCallbacks()
- signals := make(chan os.Signal, 1)
- signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM)
- go func() {
- slog.Debug("starting callback loop")
- for {
- select {
- case <-callbacks.Quit:
- slog.Debug("quit called")
- t.Quit()
- case <-signals:
- slog.Debug("shutting down due to signal")
- t.Quit()
- case <-callbacks.Update:
- err := DoUpgrade(cancel, done)
- if err != nil {
- slog.Warn(fmt.Sprintf("upgrade attempt failed: %s", err))
- }
- case <-callbacks.ShowLogs:
- ShowLogs()
- case <-callbacks.DoFirstUse:
- err := GetStarted()
- if err != nil {
- slog.Warn(fmt.Sprintf("Failed to launch getting started shell: %s", err))
- }
- }
- }
- }()
- // Are we first use?
- if !store.GetFirstTimeRun() {
- slog.Debug("First time run")
- err = t.DisplayFirstUseNotification()
- if err != nil {
- slog.Debug(fmt.Sprintf("XXX failed to display first use notification %v", err))
- }
- store.SetFirstTimeRun(true)
- } else {
- slog.Debug("Not first time, skipping first run notification")
- }
- if IsServerRunning(ctx) {
- slog.Info("Detected another instance of ollama running, exiting")
- os.Exit(1)
- } else {
- done, err = SpawnServer(ctx, CLIName)
- if err != nil {
- // TODO - should we retry in a backoff loop?
- // TODO - should we pop up a warning and maybe add a menu item to view application logs?
- slog.Error(fmt.Sprintf("Failed to spawn ollama server %s", err))
- done = make(chan int, 1)
- done <- 1
- }
- }
- StartBackgroundUpdaterChecker(ctx, t.UpdateAvailable)
- t.Run()
- cancel()
- slog.Info("Waiting for ollama server to shutdown...")
- if done != nil {
- <-done
- }
- slog.Info("Ollama app exiting")
- }
|