lifecycle.go 1.8 KB

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