Comments (16)
You cant really use multiprocessing with asyncio. You'll lost the event loop. I guess that's your problem.
from panoramisk.
Is there any best practice or example I can follow to run two instances of panoramisk together (which is assuming, I need two instances, to run events and action simultaneously)
I have searched a lot, but there really isn't much out there, and not much guidance in general and wrt panoramisk specifically.
from panoramisk.
I think there is no benefits to have more than on instance per process since they will use the same event loop. Why an instance is not enough for you ? Is the event loop lagging due to high traffic ?
You can try to use two instance with two event loop (in two different thread). But this is really painfull
from panoramisk.
Is there any best practice or example I can follow to run two instances of panoramisk together (which is assuming, I need two instances, to run events and action simultaneously)
Yon dont need two instances of panoramisk if you use one asterisk, if asterisk more than one:
import asyncio
from panoramisk.manager import Manager
manager_local = ...
manager_remote = ...
async def ami_local_callback(mngr, msg):
print(msg)
async def ami_remote_callback(mngr, msg):
print(msg)
def main():
manager_local.register_event('*', callback=ami_local_callback)
manager_remote.register_event('*', callback=ami_remote_callback)
manager_local.connect()
manager_remote.connect()
try:
manager_local.loop.run_forever()
except KeyboardInterrupt:
manager_remote.close()
manager_local.loop.close()
if __name__ == '__main__':
main()
from panoramisk.
I think there is no benefits to have more than on instance per process since they will use the same event loop. Why an instance is not enough for you ? Is the event loop lagging due to high traffic ?
My requirement is to listen continuously to events from Asterisk, and send an action once every minute and process the result of both. I only have one Asterisk server, and action/response and events has to come from it.
I could not find a means to do both, simultaneously, in same event loop, which is why I thought of running two event loops.
From the answers I now understand that single event loop is sufficient for simultaneously listening for events and sending actions and getting its response. But so far I am unable to figure out how.
from panoramisk.
Yon dont need two instances of panoramisk if you use one asterisk
Thanks for the reply, I only have one asterisk, but want both events and actions response from it, continuously.
Going through the example, I know how to listen to events, and send actions and get response. But could not figure out how to combine both in a single program.
from panoramisk.
But could not figure out how to combine both in a single program.
@manager.register_event('*')
def callback(manager, message):
if message.Event == 'FullyBooted':
response = await manager.send_action({'Action': 'Status'})
print(response)
elif message.Event == 'Hangup':
response = await manager.send_action({'Action': 'Status'})
print(response)
from panoramisk.
@manager.register_event('*') def callback(manager, message): if message.Event == 'FullyBooted': response = await manager.send_action({'Action': 'Status'}) print(response) elif message.Event == 'Hangup': response = await manager.send_action({'Action': 'Status'}) print(response)```
Thanks for this example.
One problem I see with this is that, for firing actions, I need an incoming event like FullyBooted
or Hangup
and will not work if I need to send action once every minute (for example).
One work around I can think of is to send a Ping
action at the beginning and on receiving the reply send my action, sleep for a minute and then send ping again.
If there are no better way, I can settle for this.
from panoramisk.
One problem I see with this is that, for firing actions, I need an incoming event like
FullyBooted
orHangup
and will not work if I need to send action once every minute (for example).
you can use aiocron for this and send action every 1,30,60, etc seconds
from panoramisk.
loop_manager = asyncio.get_event_loop()
manager = Manager(
loop=loop_manager,
host=HOST,
port=PORT,
username=USERNAME,
secret=SECRET
)
@manager.register_event('*')
def callback(manager, message):
print(message)
async def ping():
while True:
await manager.connect()
response = await manager.send_action({'Action': 'Ping'})
print(response)
await asyncio.sleep(5)
def main():
manager.connect()
try:
loop_manager.create_task(ping())
manager.loop.run_forever()
except KeyboardInterrupt:
manager.loop.close()
if __name__ == '__main__':
main()
from panoramisk.
Very bad example.
from panoramisk.
I think I got this correctly. The code works fine, but not sure if there is some non obvious errors.
import asyncio
import logging
from pprint import pprint
from panoramisk import Manager
class EventsListener:
def __init__(self, options):
self.loop = asyncio.get_event_loop()
self.queue = asyncio.Queue()
self.manager = Manager(loop=self.loop, **options)
self.manager.log.addHandler(logging.NullHandler())
self.manager.register_event("*", self.handle_events)
async def handle_message(self):
while True:
message = await self.queue.get()
pprint (message)
self.queue.task_done()
async def handle_actions(self):
while True:
response = await self.manager.send_action({'Action': 'Status'})
self.queue.put_nowait(response)
await asyncio.sleep(10)
async def handle_events(self, manager, message):
event = message.event
await self.queue.put(event)
async def connect(self):
await self.manager.connect()
t1 = asyncio.create_task(self.handle_message())
t2 = asyncio.create_task(self.handle_actions())
await t1
await t2
def run(self):
self.loop.run_until_complete(self.connect())
self.loop.run_forever()
If this is correct, I will make a PR with a clean running example, so that others don't have to waste time reinventing this.
from panoramisk.
I dont really understand why you need a queue with events/responses. It's weird to mix both in the same queue. Also you should try/expept in while True loops to avoid failures.
from panoramisk.
I dont really understand why you need a queue with events/responses.
Its easy to process all the events and action responses in a single place. Having an async queue will also let the receive loop of panoramisk run with out any block, as all processing is happening at the other end of the queue. It is bit weird to have two types of messages from the queue, but I find it easier to handle both of them together.
Also you should try/expept in while True loops to avoid failures.
Yes, this was meant to be a simple example code illustrating the technique.
Shall I raise a PR for including this in examples/
?
from panoramisk.
Yeah sure. Why not
from panoramisk.
Hi @raj2569,
I confirm that you can use the same Panoramisk instance to send actions and receive events.
The only theoretical drawback you might have is that if you have a very long blocking statement in your treatment (CPU or blocking I/O) AND you are very sensitive to execute quickly a piece of code when you receive a specific event, it might be a problem, but I never had this situation from my professional life.
In case of you are in this situation, you might use an external queue, that could be a Redis, PostgreSQL, RabbitMQ or Kafka queue, to have another processes to handle it, but, again, you will increase the complexity of your technical stack.
Based on the content of this issue, the original question seems answered, I'm closing it.
Don't hesitate to re-open in case of extra question.
Have a nice week-end !
from panoramisk.
Related Issues (20)
- Handling AGI errors HOT 6
- How to get Variable values in FastAGI Script HOT 3
- How to read Asterisk Variable values in fast_agi script HOT 1
- panoramisk not capturing result of Async AGI command HOT 2
- Missed body from UserEvent HOT 2
- Messages Wrong Way Round?
- Avoid Direct Creation Of Future And Task Objects
- asyncio.start_server no longer needs parameter loop=loop HOT 2
- Limit the number of reconnection attempts to asterisk
- Originate example doesn't works.
- how to parse output of actions to json HOT 1
- Incomplete AMI Action Response HOT 5
- trying something simple from the example... HOT 2
- Error after callee answer HOT 3
- Adding an agent into a queue HOT 2
- Use of "@coroutine" decorator. (deprecated since Python 3.8) HOT 2
- Need one example how to call post API async mode
- error using for playDTMF HOT 1
- PyPi update HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from panoramisk.