2013-03-05 1 views
3

Je rencontre souvent des problèmes lorsque je veux rapidement faire un truc simple sur un ensemble d'objets. Mon choix naturel est d'utiliser IPython Parallel pour sa simplicité, mais souvent je dois faire face à des objets non picables. Après avoir essayé pendant quelques heures, je me résigne généralement à exécuter mes tâches du jour au lendemain sur un seul ordinateur, ou à faire une chose stupide, comme diviser les choses de manière semi-manuelle pour exécuter plusieurs scripts python.Tâches parallèles simultanées avec IPython Parallel (ou un autre paquet) en fonction des objets non saisissables

Pour donner un exemple concret, supposons que je souhaite supprimer toutes les clés d'un compartiment S3.

Ce que je fais normalement sans penser est:

import boto 
from IPython.parallel import Client 

connection = boto.connect_s3(awskey, awssec) 
bucket = connection.get_bucket('mybucket') 

client = Client() 
loadbalancer = c.load_balanced_view() 

keyList = list(bucket.list()) 
loadbalancer.map(lambda key: key.delete(), keyList) 

Le problème est que l'objet Key dans boto est unpickable (*). Cela se produit très souvent dans des contextes différents pour moi. C'est aussi un problème avec le multiprocessing, execnet, et tous les autres frameworks et libs que j'ai essayés (pour des raisons évidentes: ils utilisent tous le même pickler pour sérialiser les objets).

Est-ce que vous avez aussi ces problèmes? Existe-t-il un moyen de sérialiser ces objets plus complexes? Dois-je écrire mon propre pickler pour ces objets particuliers? Si oui, comment puis-je dire à IPython Parallel de l'utiliser? Comment écrire un pickler?

Merci!


(*) Je suis conscient que je peux simplement faire une liste des noms clés et faire quelque chose comme ceci:

loadbalancer.map(lambda keyname: getKey(keyname).delete()) 

et définir la fonction getKey dans chaque moteur du groupe IPython . Ceci est juste un exemple particulier d'un problème plus général que je trouve souvent. Peut-être que c'est un mauvais exemple, car il peut être facilement résolu d'une autre manière.

+2

Je suis sûr que les tâches sont assez embarrassés sans vous moquer d'eux sur le SO! –

Répondre

0

IPython rassemble les gens;). Donc, d'après ce que j'ai pu rassembler, le problème avec les objets décapants sont leurs méthodes. Alors peut-être au lieu d'utiliser la méthode de key pour le supprimer vous pouvez écrire une fonction qui le prend et le supprime. Peut-être d'abord obtenir une liste de dict avec les informations pertinentes sur chaque touche, puis ensuite appeler une fonction delete_key(dict) que je vous laisse à écrire parce que je ne sais pas comment gérer les touches s3.

Est-ce que cela fonctionnerait?


Sinon, il se pourrait que cela fonctionne: simplement au lieu d'appeler la méthode de l'instance, appelez la méthode de la classe avec l'instance comme argument. Donc, au lieu de lambda key : key.delete(), vous feriez lambda key : Key.delete(key). Bien sûr, vous devez pousser la classe vers les nœuds, mais cela ne devrait pas poser de problème. Un exemple minimal:

class stuff(object): 
     def __init__(self,a=1): 
      self.list = [] 
     def append(self, a): 
      self.list.append(a) 

    import IPython.parallel as p 
    c = p.Client() 
    dview = c[:] 

    li = map(stuff, [[]]*10) # creates 10 stuff instances 

    dview.map(lambda x : x.append(1), li) # should append 1 to all lists, but fails 

    dview.push({'stuff':stuff}) # push the class to the engines 
    dview.map(lambda x : stuff.append(x,1), li) # this works. 
Questions connexes