lifecycle.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. package lifecycle
  2. import (
  3. "context"
  4. "fmt"
  5. "log"
  6. "log/slog"
  7. "github.com/jmorganca/ollama/app/store"
  8. "github.com/jmorganca/ollama/app/tray"
  9. )
  10. func Run() {
  11. InitLogging()
  12. ctx, cancel := context.WithCancel(context.Background())
  13. var done chan int
  14. t, err := tray.NewTray()
  15. if err != nil {
  16. log.Fatalf("Failed to start: %s", err)
  17. }
  18. callbacks := t.GetCallbacks()
  19. go func() {
  20. slog.Debug("starting callback loop")
  21. for {
  22. select {
  23. case <-callbacks.Quit:
  24. slog.Debug("QUIT called")
  25. t.Quit()
  26. case <-callbacks.Update:
  27. err := DoUpgrade(cancel, done)
  28. if err != nil {
  29. slog.Warn(fmt.Sprintf("upgrade attempt failed: %s", err))
  30. }
  31. case <-callbacks.ShowLogs:
  32. ShowLogs()
  33. case <-callbacks.DoFirstUse:
  34. err := GetStarted()
  35. if err != nil {
  36. slog.Warn(fmt.Sprintf("Failed to launch getting started shell: %s", err))
  37. }
  38. }
  39. }
  40. }()
  41. // Are we first use?
  42. if !store.GetFirstTimeRun() {
  43. slog.Debug("First time run")
  44. err = t.DisplayFirstUseNotification()
  45. if err != nil {
  46. slog.Debug(fmt.Sprintf("XXX failed to display first use notification %v", err))
  47. }
  48. store.SetFirstTimeRun(true)
  49. } else {
  50. slog.Debug("Not first time, skipping first run notification")
  51. }
  52. if IsServerRunning(ctx) {
  53. slog.Debug("XXX detected server already running")
  54. // TODO - should we fail fast, try to kill it, or just ignore?
  55. } else {
  56. done, err = SpawnServer(ctx, CLIName)
  57. if err != nil {
  58. // TODO - should we retry in a backoff loop?
  59. // TODO - should we pop up a warning and maybe add a menu item to view application logs?
  60. slog.Error(fmt.Sprintf("Failed to spawn ollama server %s", err))
  61. done = make(chan int, 1)
  62. done <- 1
  63. }
  64. }
  65. StartBackgroundUpdaterChecker(ctx, t.UpdateAvailable)
  66. t.Run()
  67. cancel()
  68. slog.Info("Waiting for ollama server to shutdown...")
  69. if done != nil {
  70. <-done
  71. }
  72. slog.Info("Ollama app exiting")
  73. }