MultiThreading in AWS lambda using Python3 - python

I am trying to implement Multithreading in AWS lambda. This is a Sample code that defines the format of my original code which I am trying to execute in lambda.
import threading
import time
def this_will_await(arg,arg2):
print("Hello User")
print(arg,arg2)
def this_should_start_then_wait():
print("This starts")
timer = threading.Timer(3.0, this_will_await,["b","a"])
timer.start()
print("This should execute")
this_should_start_then_wait()
In my local Machine, this code is working fine. The output I am receiving is:
This starts
This should execute
.
.
.
Hello User
('b', 'a')
Those 3 . represents that it waited for 3 seconds to complete the execution.
Now when I execute the same thing in AWS lambda. I am only receiving
This starts
This should execute
I think it's not calling the this_will_await() function.

Have you tried adding timer.join()? You'll need to join the Timer thread because otherwise the Lambda environment will kill off the thread when the parent thread finishes.
This code in a Lambda function:
import threading
import time
def this_will_await(arg,arg2):
print("Hello User")
print(arg,arg2)
def this_should_start_then_wait():
print("This starts")
timer = threading.Timer(3.0, this_will_await,["b","a"])
timer.start()
timer.join()
print("This should execute")
this_should_start_then_wait()
def lambda_handler(event, context):
return this_should_start_then_wait()
Produces this output:
This starts
Hello User
b a
This should execute

Related

Prefect Python program runs before scheduled time

My program always runs on startup instead of the scheduled time, maybe i'm just misunderstanding something but I can't say why it's doing this.
from prefect import flow, task, get_run_logger
from prefect.deployments import Deployment
from prefect.orion.schemas.schedules import (
CronSchedule,
IntervalSchedule,
RRuleSchedule,
)
#task(retries=2, retry_delay_seconds=5)
def say_hello():
print("hello")
return True
#flow(name="leonardo_dicapriflow")
def leonardo_dicapriflow(name: str):
say_hello()
return
deployment = Deployment.build_from_flow(
flow=leonardo_dicapriflow,
name="email-deployment",
version=1,
tags=["demo"],
schedule=CronSchedule(cron=("55 11 3 10 *") )
)
deployment.apply()
leonardo_dicapriflow("Leo")
Photo of my error screen
So remove the last line of the code and it will be fine
leonardo_dicapriflow("Leo")
apparrently it was running twice, one of them happened to be on start up.

Run two python function in parallel does not produce result

I have two python function which I want to run in parallel. I don't want sub_task function to wait for main_task function.
from threading import Thread
from multiprocessing import Process
from time import sleep,time
def main_task():
while True:
sleep(2)
print('main task running')
def sub_task():
while True:
sleep(5)
print('sub task running')
When I used thread this way, I can see output
q=Thread(target = main_task).start()
s=Thread(target = sub_task).start()
But when I used Process this way, I cannot see ouput
q=Process(target = main_task).start()
s=Process(target = sub_task).start()
So what is wrong with the implementation.

Python: how to set a time to trigger a function?

How can I set a timer to run a function? right now I manually run the function. But what if I want to tell Python to run it in like 1 hour? how can I achieve this task?
Additionally, how about trying to run it at say 5pm today or tomorrow?
I tried the following but does not really work. What did I miss?
import datetime
from threading import timer
def hello_world():
print("hello world")
delta_t = datetime.time(0,1,0)
Timer(delta_t, hello_world)
import threading
def task():
print("hello world ")
timer = threading.Timer(5.0, task)
timer.start()

Python threading - How to repeatedly execute a function in a separate thread?

I have this code:
import threading
def printit():
print ("Hello, World!")
threading.Timer(1.0, printit).start()
threading.Timer(1.0, printit).start()
I am trying to have "Hello, World!" printed every second, however when I run the code nothing happens, the process is just kept alive.
I have read posts where exactly this code worked for people.
I am very confused by how hard it is to set a proper interval in python, since I'm used to JavaScript. I feel like I'm missing something.
Help is appreciated.
I don't see any issue with your current approach. It is working for me me in both Python 2.7 and 3.4.5.
import threading
def printit():
print ("Hello, World!")
# threading.Timer(1.0, printit).start()
# ^ why you need this? However it works with it too
threading.Timer(1.0, printit).start()
which prints:
Hello, World!
Hello, World!
But I'll suggest to start the thread as:
thread = threading.Timer(1.0, printit)
thread.start()
So that you can stop the thread using:
thread.cancel()
Without having the object to Timer class, you will have to shut your interpreter in order to stop the thread.
Alternate Approach:
Personally I prefer to write a timer thread by extending Thread class as:
from threading import Thread, Event
class MyThread(Thread):
def __init__(self, event):
Thread.__init__(self)
self.stopped = event
def run(self):
while not self.stopped.wait(0.5):
print("Thread is running..")
Then start thread with object of Event class as:
my_event = Event()
thread = MyThread(my_event)
thread.start()
You'll start seeing the below output in the screen:
Thread is running..
Thread is running..
Thread is running..
Thread is running..
To stop the thread, execute:
my_event.set()
This provides more flexibility in modifying the changes for the future.
What might be an issue is that you are creating a new thread each time you are running printit.
A better way may be just to create one thread that does whatever you want it to do and then you send an event to stop it when it is finished for some reason:
from threading import Thread,Event
from time import sleep
def threaded_function(evt):
while not evt.is_set():
print "running"
sleep(1)
if __name__ == "__main__":
e=Event()
thread = Thread(target = threaded_function, args = (e, ))
thread.start()
sleep(5)
e.set() # tells the thread to exit
thread.join()
print "thread finished...exiting"
I run it in python 3.6.It works ok as you expected .
I have used Python 3.6.0.
And I have used _thread and time package.
import time
import _thread as t
def a(nothing=0):
print('hi',nothing)
time.sleep(1)
t.start_new_thread(a,(nothing+1,))
t.start_new_thread(a,(1,))#first argument function name and second argument is tuple as a parameterlist.
o/p will be like
hi 1
hi 2
hi 3
....

Python BackgroundScheduler program crashing when ran from another module

I am trying to build a application that will run a bash script every 10 minutes. I am using apscheduler to accomplish this and when i run my code from terminal it works like clock work. However when i try to run the code from another module it crashes i suspect that the calling module is waiting for the "schedule" module to finish and then crash when that never happens.
Error code
/bin/bash: line 1: 13613 Killed ( python ) < /tmp/vIZsEfp/26
shell returned 137
Function that calls schedule
def shedual_toggled(self,widget):
prosessSchedular.start_background_checker()
Schedule Program
def schedul_check():
"""set up to call prosess checker every 10 mins"""
print "%s check ran" %(counter)
counter =+ 1
app = prosessCheckerv3.call_bash() < calls the bash file
if app == False:
print "error with bash"
return False
else:
prosessCheckerv3.build_snap_shot(app)
def start_background_checker():
scheduler = BackgroundScheduler()
scheduler.add_job(schedul_check, 'interval', minutes=10)
scheduler.start()
while True:
time.sleep(2)
if __name__ == '__main__':
start_background_checker()
this program simply calls another ever 10 mins. As a side note i have been trying to stay as far away from multi-threading as possible but if that is required so be it.
Well I managed to figure it out my self. The issue that GTK+ is not thread safe so the timed module need to be either be ran in another thread or else you can realise/enter the thread before/after calling the module.
I just did it like this.
def shedual_toggeld(self,widget):
onOffSwitch = widget.get_active()
""" After main GTK has logicly finished all GUI work run thread on toggel button """
thread = threading.Thread(target=self.call_schedual, args=(onOffSwitch,))
thread.daemon = True
thread.start()
def call_schedual(self, onOffSwitch):
if onOffSwitch == True:
self.sch.start_background_checker()
else:
self.sch.stop_background_checker()
This article goes through it in more detail. Hopefully some one else will find this useful.
http://blogs.operationaldynamics.com/andrew/software/gnome-desktop/gtk-thread-awareness

Categories