Hy, I have made a java application using asterisk-java and from it I can receive a call and can initiate outbound as well. But I am facing one problem that whenever I bulk outbound calls to say 50k users, the application can handle only those who answered the calls not those who unanswered or didn't responded. Also as I have set the value of
OriginateAction.setAsync(true)
in my outbound calling application so I am getting success response to every call, which means call is successfully initiated, but if this value is not set then although I can check the response (error: incase the user didn't responded the call), but then in this case outbound bulk drops from 50k to 3k.
My Ideal solution would be if the call is not answered and is hung up eventually then I can redirect it to some AGI script, which would show its record (hangup cause, Answered/Busy/etc)
Kindly guide.
You have manage number of call yourself.
Asterisk not designed to know how many calls at once your hardware/trunks can support,that interface just for place SINGLE call.
Check vicidial dialler or other project writed before.
Related
In Java in a web service, I have a requirement I want to return the response to the user after configured threshold time reaches and wants to continue processing after that.
Let's say I have a service it does step1, step 2, and the configured threshold is 1 second. Let's say step1 is completed at 1 second I want to return an acknowledgment response to the user and continue processing with step2 and wants to store response in DB or something like that.
Please let me know if anyone has any solutions or thoughts on this problem
There are multiple ways to achieve this
HTTP Layer
On HTTP layer, if the response comes back before the threshold, then I'd be tempted to send back a 200 Success.
However, if it takes more time than the threshold, you could use 202 Accepted
Looking at the RFC, its use case looks like this
6.3.3. 202 Accepted
The 202 (Accepted) status code indicates that the request has been
accepted for processing, but the processing has not been completed.
The request might or might not eventually be acted upon, as it might
be disallowed when processing actually takes place. There is no
facility in HTTP for re-sending a status code from an asynchronous
operation.
The 202 response is intentionally noncommittal. Its purpose is to
allow a server to accept a request for some other process (perhaps a
batch-oriented process that is only run once per day) without
requiring that the user agent's connection to the server persist
until the process is completed. The representation sent with this
response ought to describe the request's current status and point to
(or embed) a status monitor that can provide the user with an
estimate of when the request will be fulfilled.
Now, of course, instead of having a mix of 200 and 202, you could just return 202 everytime
Application Layer
In your application layer, you'll typically want to make use of asynchronous processing for this purpose.
There are multiple ways to leverage this way of working, you can:
Post a message on a queue/topic and let a message broker take care of dispatching it to another part of the app, or another app and let this part do the processing
Save the request inside of a database, and have another service poll the database for new requests, similar to queueing explained above, without JMS
If you're using Java EE, your EJB container allows you to work with #Asynchronous which will call a method asynchronously and return (so you'll be able to return 202)
If you're using Spring, it has an #Async annotation for the same purpose as hereabove
There are definitely other methods you could use to achieve this use case, but I think the ones I presented are the most common ones
My programme is a notification service, it basically receives http requests(client sends notifications) and forwards them to a device.
I want it to work the following way:
receive client notification request
save it to the database(yes, i need this step, its mandatory)
async threads watch new requests in database
async threads forward them to the destination(device).
In this case the programme can send client confirmation straight away after the step 2).
Thus, not waiting for the destination to respond(device response time can be too long).
If I stored client notification in memory i would use BlockingQueue. But I need to persist my notifications in db. Also, I cannot use Message Queues, because clients want rest endpoints to send notifications.
Help me to work out the architecture of such a mechanism.
PS In Java, Postgresql
Here are some ideas that can lead to the solution:
Probably the step 2 is mandatory to make sure that the request is persisted so that rather it will be queried. So we're talking about some "data model" here.
With this in mind, if you "send" the confirmation "right away after the step 2" - what if later you want to do some action with this data (say, send it somewhere) and this action doesn't succeed. You store it on disk? what happens if the disk is full?
The most important question is what happens to your data model (in the database) in this case? Should the entry in the database still be there or the whole "logical" action has failed? This is something you should figure out depending on the actual system the answers can be different.
The most "strict" solution would use transactions in the following (schematic) way:
tr = openTransaction()
try {
saveRequestIntoDB(data);
forwardToDestination(data);
tr.commit();
} catch(SomeException ex) {
tr.rollback();
}
With this design, if something goes wrong during the "saveRequest" step - well, nothing will happen. If the data is stored in db, but then forwardToDestination fails - then the transaction will be rolled back and the record won't be stored in DB.
If all the operations succeed - the transaction will be committed.
Now It looks like you still can use the messaging system in step 4. Sending message can be fast and won't add any significant overhead to the whole request.
On the other hand, the benefits are obvious:
- Who listens to these "notifications"? If you send something and only one service should receive and process the notification how do you make sure that others won't get it? How would you implement the opposite - what if all the services should get the notification and process it independently?
These facilities are already implemented by any descent messaging system.
I can't really understand the statement:
I cannot use Message Queues, because clients want rest endpoints to send notifications.
Since the whole flow is originated by the client's request I don't see any contradication here. The code that is called from rest endpoint (which is after all is a logic entrypoint that should be implemented by you) can call the database, persist the data and then send the notification...
How to make sure that a particular DB transaction happens only once. I am making a payment request from my mobile (more than once), but the backend should only execute only one. Once the request is executed its status is marked as COMPLETED. But in case of multiple request, before one request gets completed another starts is execution so the payment is done twice before the status to be marked COMPLETED. How to solve this problem? I am using Java as backend. How can synchronize() help to solve this problem?
You can try to add a lock around the code. That way only one thread can enter at any given time.
If you make one request, then the other request have to wait until the request is finish.
This is a known issue as Double Post.
Preventing parallel access to the method with Synchronize and lock will not help you, as the requests will be proceed in series.
Using client Side methods may help, but is not enough, as many things may happen at client side.
If you want to prevent it at Server Side (this is the correct way to do), you can add a hidden field to the client form (some unique hash string) and send it to the server with every request. In the Server side component, you can check if a request with that hash is already received, and if so, return an error code to client.
You can also persist the hash with your Data and make it a unique field, so the first request that reach your database will be persisted, and the others will see unique field errors.
While the Servlet 3.0 spec has request.startAsync() and asyncContext.start(),
why has it not provided a asyncContext.stop() or asyncContext.cancel() to initiate necessary clean-up on the server-side ?
Pls view this in the context of this other question to understand where I am coming from.
One HTTP request starts the Async processing and returns a
.../outstandingRequests/requestId link to the client.
Another HTTP request calls DELETE on that link to cancel the request
In this case, if I had a way to clean-up the server-side (servlet container stuff like AsyncListeners), instead of having to call asyncContext.complete() which will probably try and send a response back to the client, it will make sense. Doesnt it ?
In this scenario, call 1 is still hanging there, waiting for its response when call 2 comes in and wants to kill it. In this scenario, why would you not want to call complete() on call 1, thus finishing that call so that client stops waiting? You would probably want to set the status code to something other than 200 in this type of situation, but complete seems too be the best option given any scenario because it returns control back to the original caller and performs any request related cleanup work.
When a timeout happens, which is an error, the container calls complete (with a non-200 response code I imagine). The scenario you describe is similar to a timeout (albeit a forced timeout), so why not do the same thing the container does. Just call something like this before calling complete:
ac.getResponse().setStatus(500);
Any maybe write something to the output stream describing what caused this error.
So, to explain this, I'll start out by going through the application stack.
The system is running JSP with jQuery on top, talking through a controller layer with a service layer, which in turn utilizes a persistence layer implemented in Hibernate.
Now, traditionally, errors like having overlapping contracts has been handled through throwing exceptions up through the layers until they're translated into an error message for the user.
Now I have an object that at any given time can only be tied to one contract. At the moment, when I save a contract, I look at all of these objects and check if they're already covered by an existing contract. However, since multiple clients can be saving at any given time, this introduces the risk of getting past the check on two separate contracts, leading to one object being tied to two contracts at the same time.
To combat this, the idea was to use a queue, put objects into the queue from the main thread, and then have a separate thread take them out one by one, saving them.
However, here's the problem. For one, I would like the user to know that the saving is currently happening, for another, if by accident the scenario before happens, and two contracts with the same object covering the same time is in the queue, the second one will fail, and this needs to be sent back to the user.
My initial attempt was to keep data fields on the object put into the queue, and then check against those in a blocking wait, and then throw an exception or report success based on what happens. That deadlocked the system completely.
Anyone able to point me in the right direction with regards to techniques and patterns I should be using for this?
I can't really tell why you have a deadlock without seeing your code. I can think of some other options though:
Poll the thread to see its state (not as good).
Use some kind of eventing system. You would have an event listener (OverlappingContractEventListener perhaps) and then you would trigger the event from the thread when the scenario happens. The event handler would need to persist this information somehow.
If you are going for this approach, then on the client side you will need to poll.
You can poll a specific controller (using setInterval and AJAX) that looks up the corresponding information for the object to see what state its in. This information should have been persisted by your event listener.
You can use web workers (this is supported in Chrome, Firefox, Safari, and Opera. IE will support it in 10) and perform the polling in the background.
There is one other way that doesn't involve eventing. It depends on you figuring out the source of your deadlock though. Once you fix the source of your deadlock you can do one of two things:
Perform an AJAX call to the controller. The controller will wait for the service to return information. The code to issue feedback to the user will be inside the success handler of your controller.
Use a web worker to perform the call in the background. The web worker would also perform an AJAX call and wait for the response.
Shouldn't you be doing the check for duplicate contracts in the database? Depending on the case, you can do this with a constraint, trigger, o stored procedure. If it fails, send an exception up the stack. That's normally the way to handle things like this. You can then catch the exception in jQuery and display an error:
jQuery Ajax error handling, show custom exception messages
Hope this helps.