简体   繁体   中英

Heroku Python Twitterbot — Worker Dyno Refreshes Daily

I have a Python Twitterbot set up with Heroku that tweets a line from a text file every 3 hours. It's been working like a charm except the Heroku worker dyno refreshes at least once a day, and then the Twitterbot tweets from the beginning of the file again, which is obviously not what I want.

Any suggestions for how to persist through the worker dyno refresh to the next untweeted line?

The code for the bot is very simple and included here:

import tweepy, time
from credentials import *
auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
auth.set_access_token(ACCESS_TOKEN, ACCESS_SECRET)
api = tweepy.API(auth)


# What the bot will tweet

filename = open('.txt','r') 
tweettext = filename.readlines() 
filename.close()

for line in tweettext: 
    api.update_status(line)
    time.sleep(10800) # Sleep for 3 hours

except tweepy.error.TweepError:
    pass

Problem : Heroku refreshes daily both filesystem and memory, so keeping variables in memory or stored on files is a no-go.

Solutions :

First of all, I've seen around people proposing to store states in environmental variables, but that gets refreshed as well, so this too is not viable...

  1. Using a DB, like Heroku's own Postgres ; then with SQL Alchemy you can store and query a timestamp and last line read. It is overkill, maybe, but this way you could store stats as well, and other niceties of having a DB. It does not take much time or code lines, and it pays off well.

  2. Using Redis' pugin for Heroku ; It does not take much effort as well, and is more simple than using a SQL DBMS. Once installed (as per link's instructions) you just need two lines of code.

Using Redis

First you need to import it from store import redis

Then try something like:

f = open('.txt','r')
# teet first line
tweetline = f.readline() 
api.update_status(tweetline)
redis.set('line', 1) # store line number
f.close()
time.sleep(10800) # Sleep for 3 hours
#tweets all other lines
while true:
    f=open('filename')
    lines=f.readlines()
    current = int(redis.get('line'))
    tweetline = lines[current]
    redis.set('line', current + 1)
    f.close()
    time.sleep(10800) # Sleep for 3 hours

Notice that sleep(10800) that you use makes the python script sleep, but the dyno will not sleep, because it is executing the python's sleep command.

If you want your dyno to sleep, just schedule (check the addons/scheduler) the program to run on a schedule (to do so, you need to change the code I posted, so that it is a one-shot script and not an infinite cycle)

Notice : I didn't yet try this out... In my dynos I personally don't have to keep a state stored.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM