jQuery post request is not sent until first post request is completed - c#

I have a function which have a long execution time.
public void updateCampaign()
{
context.Session[processId] = "0|Fetching Lead360 Campaign";
Lead360 objLead360 = new Lead360();
string campaignXML = objLead360.getCampaigns();
string todayDate = DateTime.Now.ToString("dd-MMMM-yyyy");
context.Session[processId] = "1|Creating File for Lead360 Campaign on " + todayDate;
string fileName = HttpContext.Current.Server.MapPath("campaigns") + todayDate + ".xml";
objLead360.createFile(fileName, campaignXML);
context.Session[processId] = "2|Reading The latest Lead360 Campaign";
string file = File.ReadAllText(fileName);
context.Session[processId] = "3|Updating Lead360 Campaign";
string updateStatus = objLead360.updateCampaign(fileName);
string[] statusArr = updateStatus.Split('|');
context.Session[processId] = "99|" + statusArr[0] + " New Inserted , " + statusArr[1] + " Updated , With " + statusArr[2] + " Error , ";
}
So to track the Progress of the function I wrote a another function
public void getProgress()
{
if (context.Session[processId] == null)
{
string json = "{\"error\":true}";
Response.Write(json);
Response.End();
}else{
string[] status = context.Session[processId].ToString().Split('|');
if (status[0] == "99") context.Session.Remove(processId);
string json = "{\"error\":false,\"statuscode\":" + status[0] + ",\"statusmsz\":\"" + status[1] + "\" }";
Response.Write(json);
Response.End();
}
}
To call this by jQuery post request is used
reqUrl = "AjaxPages/lead360Campaign.aspx?processid=" + progressID + "&action=updatecampaign";
$.post(reqUrl);
setTimeout(getProgress, 500);
get getProgress is :
function getProgress() {
reqUrl = "AjaxPages/lead360Campaign.aspx?processid=" + progressID + "&action=getProgress";
$.post(reqUrl, function (response) {
var progress = jQuery.parseJSON(response);
console.log(progress)
if (progress.error) {
$("#fetchedCampaign .waitingMsz").html("Some error occured. Please try again later.");
$("#fetchedCampaign .waitingMsz").css({ "background": "url(common/images/ajax_error.jpg) no-repeat center 6px" });
return;
}
if (progress.statuscode == 99) {
$("#fetchedCampaign .waitingMsz").html("Update Status :"+ progress.statusmsz );
$("#fetchedCampaign .waitingMsz").css({ "background": "url(common/images/ajax_loded.jpg) no-repeat center 6px" });
return;
}
$("#fetchedCampaign .waitingMsz").html("Please Wait... " + progress.statusmsz);
setTimeout(getProgress, 500);
});
}
But the problem is that I can't see the intermediate message. Only the last message is been displayed after a long lime of ajax loading message
Also on the browser console I just see that after a long time first requested is completed and after that the second request is completed. but there should be for getProgress ?
I have checked jquery.doc and it says that $post is an asynchronous request.
Can anyone please explain what is wrong with the code or logic?

You are in a situation discussed here:
ASP.net session request queuing
While a request for a given user's session is processed, other requests for the same session are waiting. You need to run your long function in a background thread and let the request that initiates it finish. However, the background thread will not have access to session, and you will need a different mechanism to communicate its progress.

From the information you've provided, I would suspect that it's not your javascript code that's being synchronous, but rather the server-side code. You can test this by using Firebug or Chrome's dev tools to look at the start and end times of the two AJAX requests. If I'm right, you'll see that the second request begins after half a second, but doesn't complete until after the first one.
If that's the case, possible causes are:
Running in a dev environment in Visual Studio, especially in debug mode, seems to reduce the amount of asynchronicity. The dev environment seems to like to process one request at a time.
See Igor's answer about session request queueing.
You may have code that explicitly locks resources and causes the second request to block until the long-running request is done.
One other possible culprit is the fact that most browsers only allow a limited number of concurrent requests to a particular domain. If you have a few requests pending at any given moment, the browser may just be queuing up the remaining requests until they return.

Related

Firebase Cross-platform issue - .setAsync() is setting in 2 path destinations instead of just one

I am using Firesharp for my app in c# winforms. This database is also connected to my ReactJS website which deals with the same information.
I have noticed that when I make .SetAsync calls to my app on the website and then log in to my Winforms app, my WinForms app will automatically perform the last action I did on my website to my database which is a .setAsync() action which adds some user information to a list of other user's information. Now it will not stop. Anytime I log on to my c# app, it runs it.
It makes me think there is a queue of orders in firesharp?
here is my react code. From what I can tell, it is nothing out of the ordinary:
async function handleSubmit(e) {
e.preventDefault()
var date = moment().format("MM/DD/YYYY" )
setError("")
setLoading(true)
// grab user info first then use that.
await firebaseApp.database().ref("Users/" + currentUser.uid + "/UserData").on('value', snapshot => {
if (snapshot.val() != null) {
setContactObjects({
...snapshot.val()
})
firebaseApp.database().ref("Projects/" + projectGUIDRef.current.value + "/queueList/" + userIdRef.current.value).set({
"EntryTimeStamp": date + " " + moment().format("hh:mm:ss a"),
"IsSyncing": false,
"UserId": userIdRef.current.value,
"UserName": usernameRef.current.value,
})
}
})
history.push("/Demo")
setLoading(false)
}
here is my c# winforms code of where the code is executing. For some reason, when this executes, it also updates the EntryTimeStamp field of the react code and completely sets all the information even if I delete it. It also happens if I run .set().
updateLastLogin2(authLink);
private async void updateLastLogin2(FirebaseAuthLink authLink)
{
IFirebaseConfig config = new FireSharp.Config.FirebaseConfig
{
AuthSecret = this.authLink.FirebaseToken,
BasePath = Command.dbURL,
};
IFirebaseClient client = new FireSharp.FirebaseClient(config);
string newDateTime = DateTime.Now.ToString();
if (authLink.User.DisplayName.Contains(adUserId) && authLink.User.DisplayName.Contains(adUserId))
{
await client.SetAsync("Users/" + this.authLink.User.LocalId + "/UserData/DateLastLogin", newDateTime);
}
}
Any and all help is appreciated, I've been at this for a day and a half now.
I have never used fire-sharp but this is my guess
You are calling await firebaseApp.database().ref("Users/" + currentUser.uid + "/UserData").on('value' in your react, and then in your Csharp you are calling client.SetAsync("Users/" + this.authLink.User.LocalId .
What happens is the both listeners are listening to each other and then causing a loop.
In that case it's probably better to use once instead of on if you are just using it once.
In cases where you cannot use .once, then you should use .off to turn off the listener once you are done.
firebaseApp.database().ref("Users/" + currentUser.uid + "/UserData").once('value'`
You also shouldn't be using await here since ref().on creates a listener, it doesn't return a promise.
You should also move history.push("/Demo") into your firebase database callback function so it's called after you have set data

Selenium and Aurelia, how make test wait for the page to load and HTTP calls to complete

I would like make the Test to wait until the page has loaded properly before proceeding with the next step. I used wait until but,
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(time));
var elements = wait.Until(x => x.FindElements(by));
I am facing the problem of the element being present when the data has not been fully loaded yet.This is making the test to fail. I don't want to use the Thread.Sleep(time); since it's not a very good approach to this problem.
Is there any option like the one provided by jQuery like "jQuery.active"
I am using C# with webdriver 3 to write that test. I would like to make the test to wait for the page to complete loading and all the HTTP calls to done before proceeding with the next step is there any way to do this ?. Thank you in advance
Find an element in the dynamic portion of the page and wait for it. I do this all the time and it works just fine.
Tracking of the HTTP calls can be done using the following code
var javaScriptExecutor = Browser.Driver as IJavaScriptExecutor;
Browser.Driver.Manage().Timeouts().AsynchronousJavaScript = TimeSpan.FromSeconds(5);
return javaScriptExecutor?.ExecuteAsyncScript("var cb = arguments[arguments.length - 1];" +
"if (window.webpackJsonp && document.querySelector('[aurelia-app]')) { cb('Aurelia composed') }" +
"document.addEventListener('aurelia-http-client-requests-drained', function (e) {" +
" cb('aurelia-http-client-requests-drained')" +
"}, false);");
above code uses the event aurelia-http-client-requests-drained which is triggered when all the HTTP request has been drained
For knowing if the page is composed, following code can be used
var javaScriptExecutor = Browser.Driver as IJavaScriptExecutor;
Browser.Driver.Manage().Timeouts().AsynchronousJavaScript = TimeSpan.FromSeconds(5);
return javaScriptExecutor?.ExecuteAsyncScript("var cb = arguments[arguments.length - 1];" +
"if (window.webpackJsonp && document.querySelector('[aurelia-app]')) { cb('Aurelia composed') }" +
"document.addEventListener('aurelia-composed', function (e) {" +
" cb('Aurelia App composed')" +
"}, false);");
This take advantage of the aurelia-composed

Google Geocode null reference exception

I have made a program that takes the longitude and latitude from several properties on a london property portal.
What I am to do next is send those long+lat to geocode and return the full formatted address. The below code works for a majority of URLs that I have in my geocodeURL list, but occasionally it returns a null reference exception.
When I check the URL that failed and returned the exception manually in a browser, it works fine.
If that is the case, what am I doing wrong?
for (int i = 0; i < longitude.Count; i++)
{
Console.WriteLine(longitude[i]);
Console.WriteLine(latitude[i]);
//Console.WriteLine("http://maps.google.com/maps/api/geocode/xml?latlng=" + latitude[i] + "," + longitude[i] + "&sensor=false");
geocodeURL.Add("https://maps.googleapis.com/maps/api/geocode/xml?latlng=" + latitude[i] + "," + longitude[i] + "&key=0000");
}
foreach (string i in geocodeURL)
{
try
{
var requestUri = string.Format(i);
var request = WebRequest.Create(requestUri);
var response = request.GetResponse();
var xdoc = XDocument.Load(response.GetResponseStream());
var result = xdoc.Element("GeocodeResponse").Element("result");
var fullAddy = result.Element("formatted_address").Value;
address.Add(fullAddy);
Console.WriteLine(fullAddy);
}
catch (Exception e)
{
Console.WriteLine(i);
Console.WriteLine(e);
}
}
The XMl response looks like this:
<GeocodeResponse>
<status>OK</status>
<result>
<type>street_address</type>
<formatted_address>4 Sydenham Ave, London SE26 6UH, UK</formatted_address>
One such example of the exception, and you can see the URL seems to be fine, but it throws an exception regardless... (I have blacked out the key fyi)
Google have a limit on how many results you can send in a certain amount of time. Since you are sending hundreds of requests at a time, you are probably running up against this limit and the error is google's way of telling you to either cough up some cash or gtfo.
If you don't want to pay up, you could put a Thread.Sleep(2000) (or some other wait period) every few requests to get around the limit.

http status code 500 / webpage stops refreshing

WE have an intranet webpage which is used to display information to works on monitors around our site. This webpage is automatically refreshed every 15 seconds.
All this works find, until the Database server has a problem and the webpage and no longer get a connection, and we get an error back normally an HTTP 500 error.
My solution to this has been to write a C# application that checks the HTTP status of the webpage, and if a HTTP 500 is found to close the browser and then reopen it again and display the webpage.
This application is using a timer event set to ever 30 seconds.
The problem I am having is my C# application does not always pick up the 500 error, or any other error that may cause the webpage to stop refreshing.
Below is the code I have written to try and check for the error(s)
public static void Check_Process()
{
Console.Write("checking started at {0}" + Environment.NewLine, DateTime.Now);
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(txt_url);
response = (HttpWebResponse)request.GetResponse();
// Read the error stream first and then wait.
string error = someProcess.StandardError.ReadToEnd();
Console.Write(error);
}
catch (WebException e)
{
if (e.Status == WebExceptionStatus.ProtocolError)
{
response = (HttpWebResponse)e.Response;
if ((int)response.StatusCode == 500)
{
Console.Write((int)response.StatusCode + " error found at {0}" + Environment.NewLine, DateTime.Now);
Close_webpage();
Start_webpage();
}
else if (response.StatusCode != HttpStatusCode.OK)
{
Console.Write((int)response.StatusCode + " error found at {0}" + Environment.NewLine, DateTime.Now);
Close_webpage();
Start_webpage();
}
}
}
}
The webpage is currently loaded from within the application using
public static void Start_webpage()
{
startInfo.WindowStyle = ProcessWindowStyle.Normal;
startInfo.FileName = "IExplore.exe";
startInfo.Arguments = txt_url;
someProcess = Process.Start(startInfo);
}
Hoping someone can point out where I have gone wrong, or a better way of doing this, as currently we are have to manually refresh/reload the webpage.
Do you do a complete page reload ?
How about you use ajax call instead ? You can put that in setInterval/setTimeout, and then process successful/failed responses - should make it resistant to service failures, and more user-friendly.
And yes, you probably should eliminate 500. Try/catch{msg("OMG, database is not accessible!")} type of thing :)
Ah, and the issue with your code could be the fact that your code checks database and its fine, but then the 500th user connects, and your page refresh fails.

Using webdriver PageFactory to pick certain page

I have a web project where clicking a button navigates to another page. The new page can be 1 of three possible pages depending on data in the server. (The url may be the same for 2 of those pages)
I have three classes representing expected elements on each page using the PageObject model.
What is the best way to actually find what page actually got loaded? Is there an OR type of wait that I can wait on three unique elements and get the one that actually got loaded?
Yes, it is possible to check the presence of unique element (which identifies the page) and then return respective page in the framework.
However, a test should know the page it is expecting next and should assume that the correct page has loaded and perform further actions/assertions. You can even put an assertion here to verify correct page has loaded. If a different page has loaded, then the test eventually fails as assertions would fail.
This way test becomes more readable and describes flow of application.
Also, setting up test data upfront for the tests, is always advisable. This way you would know what data is available on server and test would know which page would render.
I had a similar issue where I needed to detect if a login was for a new user (the login page then goes to a terms & conditions page rather than direct to the home page).
Initially I just waited and then tested the second page but this was just a pain so I came up with this.
To Test the result with this:
var whichScreen = waitForEitherElementText(By.CssSelector(HeaderCssUsing), "HOME SCREEN", "home", terms.getHeaderLocator(), terms.headerText, "terms", driver, MAX_STALE_RETRIES);
if(whichScreen.Item1 && whichScreen.Item2 == "terms")
{
terms.aggreeToTerms();
}
The method that this calls is :
protected Tuple<bool, string> waitForEitherElementText(By locator1, string expectedText1, string return1Ident,
By locator2, string expectedText2, string return2Ident, IWebDriver driver, int retries)
{
var retryCount = 0;
string returnText = "";
WebDriverWait explicitWait = new WebDriverWait(driver, TimeSpan.FromSeconds(globalWaitTime));
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(0.5));
while (retryCount < retries)
{
try
{
explicitWait.Until<bool>((d) =>
{
try
{
if (Equals(d.FindElement(locator1).Text, expectedText1)) { returnText = return1Ident; };
}
catch (NoSuchElementException)
{
if (Equals(d.FindElement(locator2).Text, expectedText2)) { returnText = return2Ident; };
}
return (returnText != "");
});
return Tuple.Create(true, returnText);
}
catch (StaleElementReferenceException e)
{
Console.Out.WriteLine(DateTime.UtcNow.ToLocalTime().ToString() +
":>>> -" + locator1.ToString() + " OR " + locator2.ToString() + "- <<< - " +
this.GetType().FullName + "." + System.Reflection.MethodBase.GetCurrentMethod().Name +
" : " + e.Message);
retryCount++;
}
}
return Tuple.Create(false,"");
}
The explicit wait until uses a boolean so will loop around for the full wait time (I have a very slow Test server so I set this to 60 seconds). the implicit wait is set to half a second so the element tests will attempt every half a second and loop around until either true is returned or it fails.
I use a Tuple so that I can detect which screen I am on, and in this case agree to the terms & conditions which then sets me back on my normal page path

Categories

Resources