skip to Main Content

I have a Vapor 4 application where I’m using queues to create a scheduled job. This particular test job just prints logs every five minutes. When I run the project locally everything works as expected. However, when I deploy to Heroku things start misbehaving. According to the Heroku logs, it looks like this job gets fired multiple times every five minutes. It also appears to have just stopped randomly and no longer fires. The logs say "Process exited with status 0".

Am I missing something when deploying to Heroku? How can I get the same functionality that I am seeing locally?

I have included a screenshot of all logs below as well as the contents of my procfile and any relevant code.

Update: I changed my Heroku plan from "free" to "hobby" and that stopped the server from stopping. The free plan goes to sleep after a short time and that was causing my background worker to terminate. I’m still having the issue with duplications though.

enter image description here

public func configure(_ app: Application) throws {
    
    if let databaseURL = Environment.get("DATABASE_URL"), var postgresConfig = PostgresConfiguration(url: databaseURL) {
        postgresConfig.tlsConfiguration = .forClient(certificateVerification: .none)
        app.databases.use(.postgres(
            configuration: postgresConfig
        ), as: .psql)
    }
    
    //MARK: Migrations
    //...
    
    // MARK: Queue and Jobs
    let testJob = TestJob(app: app)

    try app.queues.use(.redis(url: "redis://127.0.0.1:6379"))
    
    for i in stride(from: 0, to: 60, by: 5){
        let minutes = ScheduleBuilder.Minute(integerLiteral: i)
        app.queues.schedule(testJob).hourly().at(minutes)
    }

    try app.queues.startScheduledJobs()

    // MARK: Register Routes
    try routes(app)
}
struct TestJob: ScheduledJob {
    let app: Application
    
    
    func run(context: QueueContext) -> EventLoopFuture<Void> {
        let formatter = DateFormatter()
        
        formatter.dateStyle = .medium
        formatter.timeStyle = .long
        print("n********* Test job: (formatter.string(from: Date())) *********")
        
        return context.eventLoop.makeSucceededVoidFuture()
    }
}

Profile

web: Run serve --env production --hostname 0.0.0.0 --port $PORT
worker: Run queues --scheduled

2

Answers


  1. Did you read the tip here. Heroku might need config to keep your queues process running
    https://docs.vapor.codes/4.0/queues/

    “Workers should stay running in production. Consult your hosting provider to find out how to keep long-running processes alive. Heroku, for example, allows you to specify "worker" dynos like this in your Procfile: worker: Run queues. With this in place, you can start workers on the Dashboard/Resources tab, or with heroku ps:scale worker=1 (or any number of dynos preferred).”

    Login or Signup to reply.
  2. Have you removed in-process call from your code?

    try app.queues.startScheduledJobs()
    

    Maybe it’s happening because both in-process and independent workers were started.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search