Handling long running tasks in pika / RabbitMQ

后端 未结 6 564
没有蜡笔的小新
没有蜡笔的小新 2020-12-04 09:26

We\'re trying to set up a basic directed queue system where a producer will generate several tasks and one or more consumers will grab a task at a time, process it, and ackn

6条回答
  •  隐瞒了意图╮
    2020-12-04 10:06

    You can also set up a new thread, and process the message in this new thread, and call .sleep on the connection while this thread is alive to prevent missing heartbeats. Here is a sample code block taken from @gmr in github, and a link to the issue for future reference.

    import re
    import json
    import threading
    
    from google.cloud import bigquery
    import pandas as pd
    import pika
    from unidecode import unidecode
    
    def process_export(url, tablename):
        df = pd.read_csv(csvURL, encoding="utf-8")
        print("read in the csv")
        columns = list(df)
        ascii_only_name = [unidecode(name) for name in columns]
        cleaned_column_names = [re.sub("[^a-zA-Z0-9_ ]", "", name) for name in ascii_only_name]
        underscored_names = [name.replace(" ", "_") for name in cleaned_column_names]
        valid_gbq_tablename = "test." + tablename
        df.columns = underscored_names
    
        # try:
        df.to_gbq(valid_gbq_tablename, "some_project", if_exists="append", verbose=True, chunksize=10000)
        # print("Finished Exporting")
        # except Exception as error:
        #     print("unable to export due to: ")
        #     print(error)
        #     print()
    
    def data_handler(channel, method, properties, body):
        body = json.loads(body)
    
        thread = threading.Thread(target=process_export, args=(body["csvURL"], body["tablename"]))
        thread.start()
        while thread.is_alive():  # Loop while the thread is processing
            channel._connection.sleep(1.0)
        print('Back from thread')
        channel.basic_ack(delivery_tag=method.delivery_tag)
    
    
    def main():
        params = pika.ConnectionParameters(host='localhost', heartbeat=60)
        connection = pika.BlockingConnection(params)
        channel = connection.channel()
        channel.queue_declare(queue="some_queue", durable=True)
        channel.basic_qos(prefetch_count=1)
        channel.basic_consume(data_handler, queue="some_queue")
        try:
            channel.start_consuming()
        except KeyboardInterrupt:
            channel.stop_consuming()
        channel.close()
    
    if __name__ == '__main__':
        main()
    

    The link: https://github.com/pika/pika/issues/930#issuecomment-360333837

提交回复
热议问题