2016-08-24 4 views
1

Ich habe erfolgreich eine Lambda-Funktion (app1) erstellt, die RDS liest und schreibt.Unabhängiger Python-Subprozess von AWS Lambda-Funktion

Meine Lambda-Funktion wird in python2.7 geschrieben und als gezipptes Paket hochgeladen.

Ich habe das ZIP-Paket auf einer EC2-Instanz in derselben VPC wie meine RDS- und Lambda-Funktion erstellt und getestet.

Als nächstes fügte ich die Funktionalität zu meiner Lambda-Funktion hinzu, um einen unabhängigen Subprozess (app2) mit subprocess.popen zu öffnen und app1 zurückzugeben, während der app2-Subprozess eigenständig fortfuhr. Ich testete, dass App1 die Ausgabe seines Handlers erfolgreich zurückgab, während App2 fortfuhr, indem sie einen 60-Sekunden-Schlaf in app2 setzte und die Ausgabedatei von app2 tailte.

Ich habe die App1- und App2-Funktionalität in der EC2-Instanz erfolgreich getestet. Nach dem Hochladen des neuen Pakets scheint sich meine App1 genau wie erwartet zu verhalten und gibt sofort die Ausgabe ihres Handlers zurück, aber die App2-Funktionalität erscheint nicht als instanziiert, aber es gibt keine Protokolle, Fehler oder Ausgaben Erfassung von App2.

In app1, ich getestet, dass Subprozess arbeitete durch Ausführen eines subprocess.check_output (['ls', '- la']) vor und nach dem unabhängigen subproccess.popen, und der lokale Ordner wird mit meinen Dateien angezeigt. Es wird jedoch keine app2output-Datei wie erwartet erstellt.

Zwei Fragen

  1. Gibt es etwas Besonderes, dass ich in AWS-Lambda-Konzepte am fehlt die app2 verursacht zu "fail"? Mit "fail" bezeichne ich nicht das Erstellen der neuen Datei und das Schreiben, das Erstellen von Cloudwatch-Protokollen auf die gleiche Weise, wie es bei app1 der Fall ist, oder das Ausdrucken auf der Lambda-Konsole wie bei app1.
  2. Wie kann ich eine Ausgabe (Logging-Informationen und Fehler) für App2 in einer AWS-Lambda-Umgebung abfangen?

app1.py

import subprocess 
import sys 
import logging 
import rds_config 
import pymysql 
#rds settings 
rds_host = "rdshost" 
name = rds_config.db_username 
password = rds_config.db_password 
db_name = rds_config.db_name 
port = 3306 

logger = logging.getLogger() 
logger.setLevel(logging.INFO) 

server_address = (rds_host, port) 
try: 
    conn = pymysql.connect(rds_host, user=name, passwd=password, db=db_name, connect_timeout=5) 
except: 
    logger.error("ERROR: Unexpected error: Could not connect to MySql instance.") 
    sys.exit() 

def handler(event, context): 

    cur = conn.cursor() 
    isql = "INSERT ..." 
    cur.execute(isql) 
    conn.commit() 
    newid = cur.lastrowid 
    cur.close() 

    args = [str(newid),str(event['name'])] 

    logger.info('ARGS: '+str(args)) 
    print 'pwd: ' 
    output = subprocess.check_output(['pwd']) 
    print output 
    print 'ls -la' 
    output = subprocess.check_output(['ls','-l']) 
    print output 

    pid = subprocess.Popen([sys.executable, "app2.py"]+args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) 

    logger.info('PID: '+str(pid)) 
    output = subprocess.check_output(['ls','-l']) 
    print output 

    return "{'status':'success','newid':'"+str(newid)+"'}"; 

Die Ausgabe von "logger.info ('PID:' + str (pid))" in app1.py

ist wie: „PID : < subprocess.Popen Objekt bei 0x7f51aba2a550 > "

app2

import sys 
import logging 
from datetime import datetime 
import time 

fo = open('app2output','a+') 
fo.write("starting with: "+str(sys.argv)+"\n") 

logger = logging.getLogger() 
logger.setLevel(logging.INFO) 
logger.info("Starting with: "+str(sys.argv)+"\n") 

#log accumulated processing time 
t1 = datetime.now(); 
sleep(60) 
t2 = datetime.now(); 
tstring = "{'t1':'"+str(t1)+"','t2':'"+str(t2)+"','args':'"+str(sys.argv[1])+"'}" 
logger.info(tstring+"\n") 
fo.write(tstring+"\n") 
fo.close() 
sys.exit() 

Antwort

2

Die AWS Lambda-Umgebung wird beendet, sobald die Handler-Funktion zurückkehrt. Sie können Unterprozesse in einer AWS Lambda-Umgebung nicht im Hintergrund ausführen, nachdem Ihre Handlerfunktion abgeschlossen ist. Sie müssten Ihre Lambda-Funktion codieren, um darauf zu warten, dass der Unterprozess abgeschlossen wird.

+0

Ich dachte, das könnte das Problem sein. Ich habe nach App2 einen 60 Sekunden Schlaf zu app1 hinzugefügt, aber bevor ich den Handler zurückgab, und App2 zeigte immer noch keinen Fortschritt. Ich habe beschlossen, app2 zu einer separaten Lambda-Funktion zu machen und es auf diese Weise unabhängig zu starten. Danke für die Antwort, und es ist korrekt in Bezug auf meinen erklärten Verwendungszweck. – Lance