Fabric: Execução paralela em python3

Criado em 2 dez. 2018  ·  14Comentários  ·  Fonte: fabric/fabric

Não consegui encontrar nenhum documento sobre execução paralela para a versão de malha mais recente. É o mesmo que a versão python 2 ou está em andamento?

Obrigado!

Comentários muito úteis

@akiuni existe um PR para isso? #1912 (comentário)

Olá, acho que não.. Para ser sincero, sei como verificar isso e não sei como proceder para enviar tal modificação...

Todos 14 comentários

Sim, no entanto, o grupo Threading não suporta configurações, em particular:

config = Config(overrides={'sudo':{'password': 'changeme'}})

c = ThreadingGroup("[email protected]", "[email protected]", connect_kwargs={"password": "changeme"}, config=config)

c.run("whoami")

c.sudo("whoami") #Throws AttributeError: 'ThreadingGroup' object has no attribute 'sudo'

ThreadingGroup só permite o comando de execução.
https://github.com/fabric/fabric/issues/1899#issue -377714688

Você pode reescrever e adicionar o suporte ao comando.

O que você acha do seguinte patch para habilitar o sudo em SerialGroup e ThreadingGroup ?
( aplicado e testado em tecido 2.4 )

--- fabric-orig/group.py    2018-10-30 14:35:22.000000000 +0100
+++ fabric-patched/group.py 2019-02-18 10:16:29.186000000 +0100
@@ -183,12 +183,28 @@
             raise GroupException(results)
         return results

+    def sudo(self, *args, **kwargs):
+        results = GroupResult()
+        excepted = False
+        for cxn in self:
+            try:
+                results[cxn] = cxn.sudo(*args, **kwargs)
+            except Exception as e:
+                results[cxn] = e
+                excepted = True
+        if excepted:
+            raise GroupException(results)
+        return results

 def thread_worker(cxn, queue, args, kwargs):
     result = cxn.run(*args, **kwargs)
     # TODO: namedtuple or attrs object?
     queue.put((cxn, result))

+def thread_worker_sudo(cxn, queue, args, kwargs):
+    result = cxn.sudo(*args, **kwargs)
+    # TODO: namedtuple or attrs object?
+    queue.put((cxn, result))

 class ThreadingGroup(Group):
     """
@@ -208,6 +224,49 @@
             )
             threads.append(thread)
         for thread in threads:
+            thread.start()
+        for thread in threads:
+            # TODO: configurable join timeout
+            # TODO: (in sudo's version) configurability around interactive
+            # prompting resulting in an exception instead, as in v1
+            thread.join()
+        # Get non-exception results from queue
+        while not queue.empty():
+            # TODO: io-sleep? shouldn't matter if all threads are now joined
+            cxn, result = queue.get(block=False)
+            # TODO: outstanding musings about how exactly aggregate results
+            # ought to ideally operate...heterogenous obj like this, multiple
+            # objs, ??
+            results[cxn] = result
+        # Get exceptions from the threads themselves.
+        # TODO: in a non-thread setup, this would differ, e.g.:
+        # - a queue if using multiprocessing
+        # - some other state-passing mechanism if using e.g. coroutines
+        # - ???
+        excepted = False
+        for thread in threads:
+            wrapper = thread.exception()
+            if wrapper is not None:
+                # Outer kwargs is Thread instantiation kwargs, inner is kwargs
+                # passed to thread target/body.
+                cxn = wrapper.kwargs["kwargs"]["cxn"]
+                results[cxn] = wrapper.value
+                excepted = True
+        if excepted:
+            raise GroupException(results)
+        return results
+
+    def sudo(self, *args, **kwargs):
+        results = GroupResult()
+        queue = Queue()
+        threads = []
+        for cxn in self:
+            my_kwargs = dict(cxn=cxn, queue=queue, args=args, kwargs=kwargs)
+            thread = ExceptionHandlingThread(
+                target=thread_worker_sudo, kwargs=my_kwargs
+            )
+            threads.append(thread)
+        for thread in threads:
             thread.start()
         for thread in threads:
             # TODO: configurable join timeout

Isso honestamente seria incrível @akiuni

Seria bom obter o recurso execute() de volta ao ThreadingGroup para Fabric2.

@akiuni existe um PR para isso? https://github.com/fabric/fabric/issues/1912#issuecomment -464652728

@akiuni existe um PR para isso? #1912 (comentário)

Olá, acho que não.. Para ser sincero, sei como verificar isso e não sei como proceder para enviar tal modificação...

Precisamos mesclar isso no Fabric o mais rápido possível.

mm olhando para o código atual na v 2.5.0
https://github.com/fabric/fabric/blob/2.5.0/fabric/group.py#L127 Posso ver que este código não é mais atual e que os autores estão pensando em uma melhor maneira de implementar isso. Também sem PR eles não têm plataforma para discutir as mudanças que o código introduz. Estou olhando para isso, mas não sou um codificador especialista em python, mas vou tentar tentar como PR

Olá, não estou acostumado a git developpemen (PR é uma palavra estranha para mim), sinta-se à vontade para me dizer se posso ajudar

oi @akiuni
PR significa Pull Request, e isso significa que, se você quiser fazer uma alteração, você a traz para o código-fonte por meio de uma pull request, que pode ser tratada como uma conversa e revisada, até que seja aprovada. Quando for aprovado, as alterações introduzidas pelo PR podem ser rastreadas até um commit como eu fiz aqui: #2052
Um truque inteligente é adicionar ".patch" ao pull request (PR) como aqui: https://patch-diff.githubusercontent.com/raw/fabric/fabric/pull/2052.patch que lhe dará um diff das mudanças (como você forneceu em seu comentário anterior), mas agora, o benefício é, a conversa / revisão / ponto único de mudança como mencionei acima - obrigado por ser o primeiro com um patch para isso, eu estava procurando nisso enquanto eu criava o PR

Sudo está sendo adicionado ao grupo agora! Veja #1999

Esta página foi útil?
0 / 5 - 0 avaliações