I've made a JQuery function that makes a call to a web service, the web service returns an int but somewhere between the web service returning its value and the JQuery picking it up the data is getting lost. below is my Jquery Function:
//Make a call to a web service to get the latest number of comments for this item
WebDesign.wfGetNumberOfCommentsForWebDesignItem(vintCurrentItemID,fGetNumberOfCommentsResult);
function fGetNumberOfCommentsResult(GetNumberOfCommentsResult){
//If the number of comments returned is not zero update the the number of comments
if (GetNumberOfCommentsResult != -1 && GetNumberOfCommentsResult != null)
{
vspanCommentsNumber.html(GetNumberOfCommentsResult);
}
else
{
vspanCommentsNumber.html("Unknown");
}
}
The variable GetNumberOfCommentsResult is null, not every time but I'd say about 10% of the time. I've recorded the data that the web service returns to the JavaScript and it's not null, it's valid data, so I'm at a loss as to how the JavaScript variable is set as null. Any ideas?
Can you confirm that you are running this in a callback, when the call to the webservice is guaranteed done, and not some timed method using setTimeout ? in the second case, a race condition could explain the variable results that you are getting.
Using FireBug (add-on for Firefox), on the Console tab you can see what data is being returned from the web service call, as well as what data is being passed.
First verify the data being moved back and forth. This is the easiest way to find a truly reproducible case.
Also, it would be helpful to see how you are calling the web service on the JavaScript side.
use fiddler or something similar to monitor http requests and actually grab the response when it is null, there has to be something different about it.
Related
So I'm playing with Twilio Studio, and building a sample IVR. I have it doing a web request to an API that looks up the customer based on their phone number. That works, I can get/say their name to them.
I'm having trouble with the next step, I want to do another http request and pass the 'customer_id' that I get in webrequest1 to webrequest2, but it almost looks like all the web requests fire right when the call starts instead of in order/serialized.
It looks sorta like this;
call comes in, make http request to lookup customer (i get their customer_id and name)
split on content, if customer name is present, (it is, it goes down this decision path)
do another http request to "get_open_invoice_count", this request needs the customer_id though and not their phone number.
From looking at the logs it's always got a blank value there, even though in the "Say" step just above I can say their customer_id and name.
I can almost imagine someone is going to say I should go use a function, but for some reason I can't get a simple function to do a (got) get request.
I've tried to copy/paste this into a function and I kind of think this example is incomplete: https://support.twilio.com/hc/en-us/articles/115007737928-Getting-Started-with-Twilio-Functions-Beta-
var got = require('got');
got('https://swapi.co/api/people/?search=r2', {json: true})
.then(function(response) {
console.log(response)
twiml.message(response.body.results[0].url)
callback(null, twiml);
})
.catch(function(error) {
callback(error)
})
If this is the right way to do it, I'd love to see one of these ^ examples that returns json that can be used in the rest of the flow. Am I missing something about the execution model? I'm hoping it executes step by step as people flow through the studio, but I'm wondering if it executes the whole thing at boot?
Maybe another way to ask this question is; If I wanted to have the IVR be like
- If I know who you are, i send you down this path, if I know who you are I want to lookup some account details and say them to you and give you difference choices than if you are a stranger.
---- how do you do this?
You're right -- that code excerpt from the docs is just a portion that demonstrates how you might use the got package.
That same usage in context of the complete Twilio Serverless Function could look something like this:
exports.handler = function(context, event, callback) {
var twiml = new Twilio.twiml.MessagingResponse();
var got = require('got');
got('https://example.com/api/people/?search=r2', { json: true })
.then(function(response) {
console.log(response);
twiml.message(response.body.results[0].url);
callback(null, twiml);
})
.catch(function(error) {
callback(error);
});
};
However, another part of the issue here is that the advice in this documentation is perfectly reasonable for Functions when building an app on the Twilio Runtime, but there are a couple of unsaid caveats when invoking these functions from a Studio Flow context. Here's some relevant docs about that: https://support.twilio.com/hc/en-us/articles/360019580493-Using-Twilio-Functions-to-Enhance-Studio-Voice-Calls-with-Custom-TwiML
This function would be acceptable if you were calling it directly from an inbound number, but when you use the Function widget within a Studio flow to return TwiML, Studio releases control of the call.
If you want to call external logic that returns TwiML from a flow, and want to return to that flow later, you need to use the TwiML Redirect widget (see "Returning control to Studio" for details).
However, you don't have to return TwiML to Studio when calling external logic! It sounds like you want to make an external call to get some information, and then have your Flow direct the call down one path or another, based on that information. When using a Runtime Function, just have the function return an object instead of twiml, and then you can access that object's properties within your flow as liquid variables, like {{widgets.MY_WIDGET_NAME.parsed.PROPERTY_NAME}}. See the docs for the Run Function widget for more info. You would then use a "Split Based On..." widget following the function in your flow to direct the call down the desired branch.
The one other thing to mention here is the Make HTTP Request widget. If your Runtime Function is just wrapping a call to another web service, you might be able to get away with just using the widget to call that service directly. This works best when the service is under your control, since then you can ensure that the returned data is in a format that is usable to the widget.
I check a session object and if it does exist then call another method which would use that object indirectly. Although the second method would access this object in a few nanoseconds I was thinking of a situation when the object exactly expires between two calls. Does Session object extends its lifetime on every read access from code for preventing such a problem ? If not how to solve the problem ?
If you are going to say why I don't pass the retrieved object from first method to second one, this is because I pass the ASP.NET Page object which carries many other parameters inside it to second method and if I try to pass each of them separately, there would be many parameters while I just pass one Page object now.
Don't worry, this won't happen
If I understand your situation it works sort of this way:
Access a certain page
If session is active it immediately redirects to the second page or executes a certain method on the first page.
Second page/method uses session
You're afraid that session will expire between execution of the first and second method/page.
Basically this is impossible since your session timer was reset when just before the first page starts processing. So if the first page had active session then your second page/method will have it as well (as long as processing finishes before 20 minutes - default session timeout duration).
How is Session processed
Session is processed by means of an HTTP Module that runs on every request and before page starts processing. This explains the behaviour. If you're not familiar with HTTP Modules, then I suggest you read a bit about IHttpModule interface.
It's quite difficult to understand your question, IMHO, but I will try.
From what I understand, you're doing something like:
string helloWorld = string.Empty;
if (this.Session["myObject"] == null)
{
// The object was removed from the session or the session expired.
helloWorld = this.CreateNewMyObject();
}
else
{
// Session still exists.
helloWorld = this.Session["myObject"].ToString(); // <- What if the session expired just now?
}
or
// What if the session existed here...
if (this.Session["myObject"] == null)
{
this.Session["myObject"] = this.CreateNewMyObject();
}
// ... but expired just there?
string helloWorld = this.Session["myObject"].ToString();
I thought that Session object is managed by the same thread as the page request, which would mean that it is safe to check if object exists, than use it without a try/catch.
I were wrong:
For Cache objects you have to be aware of the fact that you’re dealing essentially with an object accessed across multiple threads
Source: ASP.NET Cache and Session State Storage
I were also wrong about not reading to carefully the answer by Robert Koritnik, which, in fact, clearly answers the question.
In fact, you are warned about the fact that an object might be removed during page request. But since Session lifespan relies on page requests, it would mean that you must take in account the removal of session variables only if your request takes longer than the session timeout (see How is Session processed in the answer by Robert Koritnik).
Of course, such situation is very rare. But if in your case, you are pretty sure that the page request can take longer than 20 minutes (default session timeout), than yes, you must take in account that an object may be removed after you've checked if it exists, but before you really use it.
In this situation, you can obviously increment the session timeout, or use try/catch when accessing the session objects. But IMHO, if the page request takes dozens of minutes, you must consider other alternatives, as Windows services, to do the work.
I'm having difficulties understanding what the problem here is but let me try it again referring to thread safety.
Thread safety issue
If this is a thread safety issue, you can always issue a lock when creating a certain session object so other parallel requests won't run into a problem by double creating your object.
if (obj == null)
{
lock (objLock)
{
if (obj == null)
{
obj = GenerateYourObject();
}
}
}
Check lock documentation on MSDN if you've never used it before. And don't forget to check other web resources as well.
I have a need to validate a field against our database to verify unique-ness. The problem I seem to be having is that the validators doValidation() exits before we've heard back from database.
How can I have the validator wait to return its payload until after we've heard from the DB?
Or perhaps a better question might be (since I think the first question is impossible), how can I set this up differently, so that I don't need to wait, or so that the wait doesn't cause the validation to automaticallly return valid?
If you're using a remote object, you can specify the method call inside your remote declaration and assign a function to the result call. The result call only runs once the remote server returns something, so it won't be run before your validation.
Do your validation call in said result function call (which you will have to create) and you should be good. Your code should go something like this:
<s:RemoteObject id="employeeService"
destination="ColdFusion"
source="f4iaw100.remoteData.employeeData"
endpoint="http://adobetes.com/flex2gateway/"
result="employeeService_resultHandler(event)"/>
**<s:method name="dataCheckCall" result="dataCheckResult(event)"/>**
<s:RemoteObject />
And in your script:
function protected dataCheckResult(event:ResultEvent):void {
**doValidate();**
}
Edit: As soon as you call "dataCheckCall" the method will start running. If, for whatever reason, you want to call this WITHIN your validator, you can do so, and then dataCheckResult will run whenever it returns with it's payload (pretend doValidate is called elsewhere). I've left a message below as well.
You are trying to fit an asynchronous process (fetching data from a DB) into a synchronous process (checking all the validators in turn).
This won't work...
You'll need to either roll your own validator framework, or use a different method of determining the legality of your controls.
P.S. The MX validators are rubbish anyway!
What I've managed to do, seems to work, mostly. I don't like it, but it at least performs the validation against the remote source.
What I've done, then, is to use an 'keyUp' event handler to spin off the database lookup portion. In the meanwhile, I set up a string variable to act as some kind of a Flag, which'll be marked as 'processing'. When the response event fires, I'll examine its contents, and either clear the flag, or set it to some kind of other error.
Then, I have created a new 'EmptyStringValidator' will check the contents of this flag, and do its job accordingly.
Its indirect, but, so far, seems to work.
I'm using mx.rpc.http.HTTPService to retrieve data from a web service. On the initial call to "loadWsData", HTTPservice accurately retrieves all the data.
However, on any and all subsequent calls HTTPService does not accurately retrieve the data; rather it always retrieves the first data set. I've confirmed that the web service is providing accurate data, both from web browsers and a ruby ws client script.
My code is below; any ideas on what could be the problem?
private function loadWsData(id:int):void
{
var webService:HTTPService = new HTTPService();
webService.url = "http://xxx.xxx.xxx.xxx:8080/profile/ + id;
webService.method = "GET";
webService.addEventListener(ResultEvent.RESULT, function(event:ResultEvent):void
{
var rawData:String = String(event.result);
var user:Object = JSON.decode(rawData).user; // User object always reflects the first data set retrieved.
....
....
});
webService.send();
}
Not sure what the issue might be, but I have a few suggestions on where to look.
First, there appears to be a bug in your code; the webService.url line is missing a quote mark. That could be messing up the URL you think you are sending. Odd, though, because I don't think what you have shown would compile, so I suspect this is just a cut-and-paste error when you posted this to StackOverflow, but I would trace out that URL just to be sure.
Also, I don't see code to remove the event listener (although it could be in the code you have abbreviated with ellipsis). Is it possible that there are lingering event listeners that are firing in addition to the ones you expect? If the original event listener fires, it will fire with the original data.
Another suggestion: instead of using a closure, try pulling it out to a separate function. That shouldn't be the issue, but maybe scope is playing a role here.
You could try to POST your results.
You might also add an event listener for FAULT, and see if there are any errors being thrown by your service request.
Is there any way to make multiple requests to the callback function in asp.net when using the ICallbackEventHandler? I need the results for each result, however, when I iterate through and call the function, I get the result only for the last call. Any way to make it return a result for each call?
This is what I am passing in via javascript:
function NoPostback() {
$(".spans").each(function(index, item) {
CallServer($(item).attr("myattr"));
});
}
In this, myattr is a custom attribute that holds a value (1..10). What I want returned is something like ('you said: ' + id) to be returned for each of the calls, so that I can go ahead and place them in the appropriate holders.
However, only one item is returned which is the final call made. For instance if there are 4 items, it returns only ('you said: 4').
Any idea on how to have all of them returned?
Thanks in advance.
Most Javascript AJAX frameworks either abort any subsequent requests if one is in progress, or they ignore previous requests and only handle the latest. The AJAX request itself will pass through the browser's XmlHttpRequest object, but the rest of the javascript code is running within the pages thread. Currently, there is no concurrent programming with javascript (however this is slated to change.)