2015-07-31 14 views
6

Se si tratta di utilizzare Lambda completamente nel modo sbagliato, fatemelo sapere.Come posso impacchettare o installare un intero programma da eseguire in una funzione AWS Lambda

Desidero installare Scrapy in una funzione Lambda e richiamare la funzione per iniziare una ricerca per indicizzazione. Il mio primo problema è come installarlo, in modo che tutti i percorsi siano corretti. Ho installato il programma utilizzando la directory da zippare come root, quindi lo zip contiene tutti i file sorgente e l'eseguibile. Sto basando i miei sforzi sull'articolo this. Nella riga che dice di includere all'inizio della mia funzione, da dove viene la variabile "processo"? Ho cercato,

var process = require('child_process'); 
var exec = process.exec; 
process.env['PATH'] = process.env['PATH'] + ':' + 
process.env['LAMBDA_TASK_ROOT'] 

ma ottengo l'errore,

"errorMessage": "Cannot read property 'PATH' of undefined", 
"errorType": "TypeError", 

Ho bisogno di includere tutti i file di libreria, o semplicemente l'eseguibile da/usr/lib? Come posso includere quella riga di codice che l'articolo dice che ho bisogno?

Edit: Ho provato a spostare il codice in un child_process.exec, e ha ricevuto l'errore

"errorMessage": "Command failed: /bin/sh: process.env[PATH]: command not found\n/bin/sh: scrapy: command not found\n" 

Ecco il mio attuale, intera funzione

console.log("STARTING"); 
var process = require('child_process'); 
var exec = process.exec; 

exports.handler = function(event, context) {  
    //Run a fixed Python command. 
    exec("process.env['PATH'] = process.env['PATH'] + ':' + process.env['LAMBDA_TASK_ROOT']; scrapy crawl backpage2", function(error, stdout) { 
     console.log('Scrapy returned: ' + stdout + '.'); 
     context.done(error, stdout); 
    }); 

}; 
+0

V'è un esempio di come "Running R statistiche in AWS Lambda" con tutti i passaggi: http://nafiux.com/blog/2015/09/11/running-r-statistics-in- aws-lambda/ –

+0

@michaelAdam sei riuscito a risolvere questo problema? Sto avendo esattamente lo stesso numero –

+0

HI @michaelAdam, sembra che [questa risposta sotto] (https://stackoverflow.com/a/40259180/39396) sia corretta; hai considerato di accettare una delle risposte alla tua domanda? –

risposta

7

Si può sicuramente eseguire i processi arbitrari dal codice Nodo in Lambda. Lo stiamo facendo per eseguire un server di gioco che elabora i turni del giocatore, per esempio. Non sono sicuro di quello che stai cercando di realizzare con Scrapy, ma ricorda che l'intera invocazione Lambda può vivere solo per un massimo di 60 secondi proprio ora su AWS! Ma se per te va bene, ecco un esempio completamente funzionante di come stiamo eseguendo il nostro arbitrario processo linux da Lambda. (Nel nostro caso, è un file binario compilato - non importa se si ha qualcosa che può essere eseguito sull'immagine Linux che usano).

var child_process = require('child_process'); 
var path = require('path'); 

exports.handler = function (event, context) { 
    // If timeout is provided in context, get it. Otherwise, assume 60 seconds 
    var timeout = (context.getRemainingTimeInMillis && (context.getRemainingTimeInMillis() - 1000)) || 60000; 
    // The task root is the directory with the code package. 
    var taskRoot = process.env['LAMBDA_TASK_ROOT'] || __dirname; 
    // The command to execute. 
    var command; 

    // Set up environment variables 
    process.env.HOME = '/tmp'; // <-- for naive processes that assume $HOME always works! You might not need this. 

    // On linux the executable is in task root/__dirname, whichever was defined 
    process.env.PATH += ':' + taskRoot; 
    command = 'bash -c "cp -R /var/task/YOUR_THING /tmp/; cd /tmp; ./YOUR_THING ARG1 ARG2 ETC"' 

    child_process.exec(command, { 
     timeout: timeout, 
     env: process.env 
    }, function (error, stdout, stderr) { 
     console.log(stdout); 
     console.log(stderr); 
     context.done(null, {exit: true, stdout: stdout, stderr: stderr}); 
    }); 
}; 
+0

Facciamo tutto ciò che copiamo in/tmp e tale perché il processo che stiamo eseguendo si aspetta che la sua posizione sia scrivibile, ma tu hai l'idea. –

+0

Ora, la quantità massima di tempo in cui una lambda può essere in vita è di 5 minuti. – ainsausti

1

Ecco una funzione lambda che corre uno script python che imposta la directory di lavoro corrente nella stessa directory della funzione Lambda. Potresti essere in grado di usarlo con alcune modifiche alla posizione relativa del tuo script python.

var child_process = require("child_process"); 

exports.handler = function(event, context) { 
    var execOptions = { 
     cwd: __dirname 
    }; 
    child_process.exec("python hello.py", execOptions, function (error, stdout, stderr) { 
     if (error) { 
      context.fail(error); 
     } else { 
      console.log("stdout:\n", stdout); 
      console.log("stderr:\n", stderr); 
      context.succeed(); 
     } 
    }); 
}; 
+1

Non è proprio quello che sto cercando. Posso eseguire facilmente un singolo script python semplicemente posizionandolo accanto alla funzione lamda nella directory zippata.Mi chiedo se sia possibile includere un'intera libreria python (o qualsiasi altra lingua per quella materia) nello zip in modo tale che la lambda possa usarla. – michaelAdam

4

un problema con il vostro esempio sta modificando node global variableprocess da

var process = require('child_process');

In questo modo non è possibile modificare la variabile d'ambiente PATH, e quindi il motivo per cui si stanno ottenendo Cannot read property 'PATH' of undefined.

Basta usare un nome diverso per la libreria child_process caricata, ad es.

//this gets updated to child_process 
var child_process = require('child_process'); 
var exec = child_process.exec; 

//global process variable is still accessible 
process.env['PATH'] = process.env['PATH'] + ':' + 
process.env['LAMBDA_TASK_ROOT'] 

//start new process with your binary 
exec('path/to/your/binary',...... 
Problemi correlati