2017-07-09 1 views
0

J'ai une méthode que je suis en train d'appeler comme une tâche de céleri:passant par exemple boto3.client à des tâches de céleri soulève erreur de sérialisation JSON

@app.task 
def launch_compute_node(client, timeout=20, wait_interval=5): 

try: 
    status = client.run_instances(
     InstanceType='t2.micro', 
     MinCount=1, 
     MaxCount=1, 
     ImageId=XXXXXXX, 
     KeyName=KEY_NAME, 
     SecurityGroupIds=[XXXXXXX, XXXXXXXX], 
     SubnetId=SUBNET_ID, 
     PrivateIpAddress=XXXXXXX, 
     TagSpecifications=[ 
     {'ResourceType': 'instance', 
      'Tags': [ 
      {'Key': 'Name', 
      'Value': NODE_NAME}]}] 
    ) 
except ClientError as ex: 
    logger.error(str(ex)) 
    return None 

state = get_instance_state(status) 
instance_id = status['Instances'][0]['InstanceId'] 
counter = timeout 

while state != 'running': 
    logger.debug('Instance not in running state, waiting...') 
    time.sleep(wait_interval) # sleep `wait_interval' seconds 
    counter = counter - 1 
    if counter <= 0: 
     logger.warning('Timed out after %s attempts' % timeout) 
     # TODO: Probably it's a good idea do terminate the failed instance here. 
     return None 

    status = client.describe_instances(InstanceIds=[instance_id]) 
    state = get_instance_state(status['Reservations'][0]) 
    instance_id = status['Reservations'][0]['Instances'][0]['InstanceId'] 
    logger.debug('Instance \'%s\' in state \'%s\'' % (instance_id, state)) 

logger.info('Instance \'%s\' ready for jobs' % instance_id) 

return instance_id 

Une méthode parfaitement son mais quand je crée une tâche de céleri je reçois :

kombu.exceptions.EncodeError: <botocore.client.EC2 object at 0x106113438> is not JSON serializable

Ce qui est logique - aucune raison pour laquelle un client EC2 boto devrait être JSON sérialisable. Mais cela me laisse dans une contrainte - sans modifier de manière significative le code, comment puis-je créer et vérifier l'état d'une instance EC2 à partir d'une tâche de céleri?

Toutes les idées sont grandement appréciées!

Répondre

1

Par défaut, tous les messages au courtier en céleri sont codés en JSON. .

Dans votre cas, vous essayez d'envoyer un objet botocore.client.EC2 et Kombu essaie de sérialiser cela afin de créer un message AMQP correct qui est stocké par le courtier et transmis à céleri. Cependant, JSON peut serialize only a limited set de types par défaut. Puisque JSON ne sait pas comment sérialiser votre objet, cette erreur est levée. Je suppose que le problème se produit lorsque vous renvoyez l'instance_id. Qu'est-ce qui se passe quand vous ne retournez rien à la place?

This article pour sérialiser les tâches Django pourrait vous être utile.

+0

Cela a du sens. J'ai choisi d'utiliser une tâche plus simple pour appeler la méthode launch_compute_node. Merci pour le lien – fiacre