Ensuring GenServer fails gracefully


I have a problem deploying my phoenix application (Can't migrate because app is down, can't start app because migrations not done)

I have now come to realize what is causing my app to fail:

  • I’m starting a long running GenServer that references my database with Repo.all
  • Since this is an initial release/deploy, my database has not been migrated yet
  • I cannot run my migration because the app is trying to start the GenServer before I can run the migration.

This seems like something that would come up during normal development, and I’d love to know if there’s a canonical way to solve this. It would probably be possible to solve this through a try/rescue block, but that seems dirty.

Are you doing that in the init callback for the GenServer? You generally want to avoid doing so. A common pattern is to have the init callback send self a message (i usually call it :post_init) to finish setup of the GenServer. Then the rest of the application boot process can happen. If the GenServer dies the application will try to restart it according to the restart policy, but your application will most likely still come up.

Yes I’m not calling it from init, but I am starting the work schedule there (which loops every 5 minutes). The initial message is set after 10 seconds which is enough to trigger the error.

I’ve come to realize that I can run the migration without running the app explicitly through console_clean or a posthook though, so it might solve my problem here.