I apologize for my being little more han a newbie in WP and ajax but I need your help. I'm not sure if it's a bug or it's simply me who cannot manage to find a solution.
I've the following situation.
I've a plugin that displays certain data from a remote mysql server. This data need to be updated periodically.
At the moment I've implemented this through AJAX, more or less, like this:
$.ajax({
type : "POST",
url: cktn_ajax_object.ajax_url,
data: params,
dataType: "json",
success: function(response) {
<< Update UI according to response >>
},
error: function(request, status, err) {
console.debug("[AjaxOnTimer Error] status: " + status);
}
});
where $.ajax is calling the relevant php script responsible for retrieving the remote mysql data. The PHP script duration is variable, according to the amount of data it fetches (Let's say, something between a few seconds and four or five minutes).
If I test the whole on my local machine, there is no problem. The ajax call duly and patiently awaits the (slow) response of the local PHP server (which is querying the remote mysql server) and eventually, upon completion, it updates my UI.
On the other hand, when I install my plugin on the production machine things don't work as expected. Just a few seconds after having placed my ajax call to the PHP server, I get the following error in the console of the browser:
Failed to load resource: connection lost. ---> admin-ajax.php
and my script fails leaving me no other clue than the word error in the 'status' parameter of the ajax call.
Apparently the heartbeat.lock-post is interfering with my ajax call.
Any idea of what am I doing wrong?
Add the following to functions.php to turn off heartbeat:
add_action( 'init', 'my_deregister_heartbeat', 1 );
function my_deregister_heartbeat() {
global $pagenow;
if ( 'post.php' != $pagenow && 'post-new.php' != $pagenow )
wp_deregister_script('heartbeat');
}
And restart the apache.
Not sure if your problem is solved. But if someone experience the same problem today, i've solved this using the Heartbeat Control plugin available here: https://wordpress.org/plugins/heartbeat-control/.
Related
I am trying to read the request body in a custom plugin by following this url
local data = kong.request.get_body()
if data then
kong.log(data)
end
I am getting the following error
2019/03/14 21:57:55 [error] 14039#0: *45 lua entry thread aborted: runtime error: /usr/local/share/lua/5.1/kong/pdk/private/phases.lua:66: no phase in kong.ctx.core.phase
stack traceback:
coroutine 0:
[C]: in function 'error'
/usr/local/share/lua/5.1/kong/pdk/private/phases.lua:66: in function 'check_phase'
/usr/local/share/lua/5.1/kong/pdk/request.lua:594: in function 'get_body'
.../Apps/troop/kong/plugins/customlog/handler.lua:72: in function <.../Apps/troop/kong/plugins/customlog/handler.lua:62>, context: ngx.timer, client: 127.0.0.1, server: 0.0.0.0:8000
Can anyone help me understand the problem here? I need to log the request body in my plugin.
Can anyone help me understand the problem here?
I need to log the request body in my plugin.
That call can only be called in the "rewrite, access or admin_api" phase.
Looking at your log output, the context you're trying to call it is ngx.timer, which is not even wrapped by Kong as one of its contexts. (More on that here)
What you could do is call "kong.request.get_body()" in a phase that can call it, store it in a temp var (using "kong.ctx.plugin" object), and then use it in the "log" phase for said plugin.
We have a small Google Apps Script webapp that handles Slack slash commands. It does some convenient things like adding, updating and querying records to our sheet, straight from Slack. Everything works just fine most of the time. However the Slack API expects an answer from the request in less than 3 seconds, or it will timeout. Our Google Apps Script is not always able to respond in that timeframe, which will only get worse as our sheet grows or our queries get more complicated.
The Slack API allows for the use of asynchronous calls using a delayed response, but that means that the Google Apps Script needs to respond immediately (within 3 seconds) and do some work in the background.
Now this is the problem
I can't figure out how to make an asynchronous call work in Google Apps Script
I know Workers are not supported in Google Apps Script and my solution below hits a wall because of ReferenceError: 'google' is not defined. (Just ignore the Payload class, it formats a Slack response)
function doPost(request) {
var responseUrl = request.parameter.response_url
// This is how I try to circumvent the lack of threads in Google Apps Script
google.script.run
// Send an asynchronous slack response with result
.withSuccessHandler(function(payload) {
UrlFetchApp.fetch(responseUrl, {
'method' : 'post',
'contentType': 'application/json',
'payload' : payload.toString()
});
})
// Send an asynchronous slack response with error message
.withFailureHandler(function(payload) {
UrlFetchApp.fetch(responseUrl, {
'method' : 'post',
'contentType': 'application/json',
'payload' : payload.toString()
});
})
// do work in the background
.sleep(5);
return new Payload("Let me think about this...").asResponse();
}
function sleep(seconds) {
Utilities.sleep(1000 * seconds);
return new Payload("I waited for " + seconds + " seconds");
}
Does anyone have any idea how to make this work? Are there any alternative solutions to handle an asynchronous request in Google Apps Script?
I'm not aware of any threading in Apps Script either and as you noticed google.script.run only works in the Apps Script frontend.
As a workaround you could use a Google Forms as your "task queue". I've put together a simple G-Form with one question and inspected its final version to get the appropriate parameter names and URL. Then I set an installable on-form-submit trigger to run my script. Here's my POC code:
function doPost(e) {
var form = 'https://docs.google.com/forms/d/e/1FAIpQLScWBM<my-form-id>CRxA/formResponse';
UrlFetchApp.fetch(form, {method:'POST', payload:'entry.505669405=' + e.parameter.example});
return ContentService.createTextOutput('OK');
}
function onForm(e) {
//triggered async from doPost via a Google Forms
SpreadsheetApp.getActive().getSheetByName('Sheet1').appendRow(e.values);
}
It worked fine on my tests and should suffice for your use case.
How to wait for the page to load like say for 5 seconds.
In my program the sites wait for browser checks for 5 seconds before showing the content, Hence I want my http.get(url) function to wait for at least 5 seconds.
Without wait it doesn't show any content.
Thanks.
Based upon your comments, I now understand what you are trying to do and have modified this answer.
Unfortunately, there is no way to configure Meteor HTTP (which really uses
request to make the service call) to "wait" after the request has been initiated before obtaining a response. The best thing for you to do is to check out PhantomJS. It is a headless browser that you can use to load and render the page and then access dynamically generated content via javascript.
Check out this answer for a brief PhantomJS example and you can use the gadicohen:phantomjs package to install for meteor.
On a side note, it can still be useful to use the below function to pause execution in Meteor, but of course this is not useful for what you are trying to solve.
Meteor._sleepForMs(5000); // pause execution for 5 seconds
the http package is built upon npm's request package. You can do it as such with the request package directly:
var request = require('request');
var reqOptions = {
url: path,
method: 'GET',
encoding: "utf8",
jar: false,
timeout: null,
body: null,
followRedirect: null,
followAllRedirects: null,
headers: {},
time:true
};
request(reqOptions, function(error, response, body) {
console.log("time: "+response.elapsedTime)
console.log(body.toString()); //res.content returned by http.get
});
require('sleep').sleep(5); //synchronously slowing execution
You might also be able to do the same by setting {time:true} in the npmOptions parameter of the http call and then synchronously
I am running into a race condition when an unknown user is trying to access a secured page.
Iron-Router code:
function secured() {
if ( Meteor.user() == null ) {
Meteor.loginWithLinkedin({
},function (err){
if(err){
console.log("Error when login with LinkedIn."+JSON.stringify(err));
}
});
}
}
Router.map(function () {this.route('customer_researchRequest', {
before: secured,
waitOn: waitOnHuman,
path: '/research/request',
template: 'customer_researchRequest',
layoutTemplate: 'customer_requestLayout'
});});
On the server:
ServiceConfiguration.configurations.remove({
service: 'linkedin'
});
ServiceConfiguration.configurations.insert({... settings ...});
If the user goes directly to /research/request, there is a race condition.
before condition fires
(on client)ServiceConfiguration.configurations has no configuration
client has exception about no linkedin service defined.
server publishes the ServiceConfiguration.configurations to the client
At this point, my solution is to hard code in the clientId and other linkedin config information into the linkedin authentication code ( Yech ).
Is there a better more elegant/correct solution?
Update #1: My solution was to tweak the meteor-linkedin package so that it expects the linkedIn clientId as an option and does not depend on the ServiceConfiguration.configuration. This way the clientId is always available.
Edited to address comment:
Maybe a different use of reactivity can help. Set up a deferred redirect to customer_researchRequest, by first diverting the user, then bringing them up
A) Have secured() save the original destination path to the session. Redirect to a page you allow without security (or a 'Loading...' page), to avoid your #3
B) when the login callback happens, save another flag to the session, indicating that #4 is no longer true
C) have a Deps.autorun redirect to the desired path when both flags become true.
Someone else may know a smarter way, (maybe waitOn should test for the config) but ...
The best solution turns out to be my "hack" of creating a forked meteor-linkedin which accepts the client configuration in the login call.
We edited the meteor-linkedin so that the Meteor.loginWithLinkedIn() call supplied the linkedIn clientId.
Currently, Meteor's ServiceConfiguration is stored in a mongo table and needs to be published from the server to client. The clientId is essentially a static configuration variable that might as well be encoded into the client code. Just putting the linkedin clientId directly in the login code turns out to be infinitely more reliable and simpler.
Even if Meteor was to 'fix' the publishing race condition, we would stick with our solution: it is bulletproof and guaranteed to work. You can borrow our code our meteor-linkedin and accounts-meteor-linkedin
The meteor dev people aren't planning on fixing the issue. I agree with this decision, it is much better to just have the (constant) client configuration on the client rather than being stored on the server and sent to the client.
Update: In the end for a variety of reasons, we almost entirely abandoning the meteor oauth code. The client-side centric approach with popup dialogs caused numerous problems. I talk about some of the issues on the 1911 bug report. We ended up triggering the oauth code ourselves server-side.
I am very new to sencha touch 2.
I want to make a http request. basically I want to connect to google (http://www.google.com) and then check the http response if it's ok or not.
I have checked this code but I always get failure...
Ext.Ajax.request({
url : 'http://www.google.com',
success : function(response, options) {
Ext.Msg.alert("Success");
},
failure : function(response, options) {
Ext.Msg.alert("Failure" + response.responseText + " "
+ options.responseText);
}
});
Later on, I want to use this functionality to implement log-in for the application.
I appreciate your help in advance.
You can switch on Chrome with params --disable-web-security. Next you have to possibility to make Ajax request ( without cross domain policy). On device you use web container not the browser to make a request.
whene I try your code it's give me success alert.
but in console I get this error
XMLHttpRequest cannot load http://www.google.com/?_dc=1330926850434. Origin http://localhost is not allowed by Access-Control-Allow-Origin.
This error is because of that google sever not allowed ajax request from domin localhost.
If you want to send requset on this url you have to use Jsonp .
There is a Cross Domain policy which restricts user to fetch data by AJAX requests directly. So, from javascript if you want to do that, you have to use a ScriptTagProxy here.
If you are going to make a login mechanism and the data resides in same server (localhost for your case), you will not get any issue because you will be making the AJAX request from "localhost" to "localhost" ie, to same domain and then there will be no issue like this.
Otherwise, if you really want it to be cross domain, you can just write a server side code (I am showing in php - you should use cURL) to connect and get data - which doesn't require JSONP.
Filename: action.php
<?php
print file_get_contents(http://www.google.com);
?>
File name: Your js file
Ext.Ajax.request({
url : 'action.php',
success : function(response, options) {
console.log(response);
Ext.Msg.alert("Success");
},
failure : function(response, options) {
Ext.Msg.alert("Failure" + response.responseText + " "
+ options.responseText);
}
});