Welcome Guest, Not a member yet? Register   Sign In
Config updates via jQuery
#1

[eluser]Narkboy[/eluser]
I have a strange side effect occuring which is bugging me. Everything works, most of the time...

Basically:

An AJAX call changes an entry in my config file via fwrite. When that returns a success, it refreshes the 'status' section of the page.

The status section displays the current status based on that config entry.

However, the status fetched by the FIRST refresh call always shows the old config value. The second one usually shows the new value, and the third one always does. It's pretty rare I need a third call (maybe 1 in 100 calls fails on both the first and second call).

I'm using a workaround whereby the AJAX call to refresh the status is always done twice, but I need to understand why this is happening.

So - running order:

Ajax Update Call - updates the config value, and returns a success notice.

1st Ajax Refresh Call - checks the config var and returns the OLD value.

2nd Ajax Refresh Call - checks tthe config var and returns the NEW value (mostly).

Both refresh calls are identical, as is the 3rd if it's needed.



I had thought that the refresh call was coming too close after the update call, but it's only actually requested after the update returns a success notice, by which time the model has finished changing the config file.

Any thoughts?

- Can post the code, but it all works and, well, there's a lot of it!

Smile
#2

[eluser]danmontgomery[/eluser]
The request is probably cached. Have you set cache: false in your jquery request?
#3

[eluser]Narkboy[/eluser]
Ok - tried various ways to disable caching and it's not making a difference. I hate things like this - am avoiding it for the moment! Any thoughts?
#4

[eluser]Narkboy[/eluser]
Right - I've had to work on someother things and just come back to this - still the same problem.

It's not a caching issue - that's confirmed.

Here's the javascript that launches the update:
Code:
[removed]
    function check_status() {
            $('#status_holder').load('/admin/cp_ajax/status_return_status');
            $('#status_actions').load('/admin/cp_ajax/status_return_actions');
    };

    $(document).ready(function() {
        $('#do_refresh').click(function () { check_status(); });
        $('#do_maintenance').click(function () { $.ajax( { url: '/admin/cp_ajax/status_change_mode/maintenance' , success: check_status() , cache: 'false' } ); });
        $('#do_testing').click(function () { $.ajax( { url: '/admin/cp_ajax/status_change_mode/testing' , success: check_status() , cache: 'false' } ); });
        $('#do_online').click(function () { $.ajax( { url: '/admin/cp_ajax/status_change_mode/online' , success: check_status() , cache: 'false' } ); });

    });
[removed]

According to Firebug, when you click any of the updatelinks, the ajax calls in check_status() are artucally laaunched first - even though check_status() is called from the 'success' event in the update call.

Basically - we check the status, then update it.

I'm not sure if this is a jQuery problem or Firebug reporting the ajax requests incorrectly, but it would seem not the later as the result matches the order in which Firebug reports the requests.

Anyone else seen this?

Success calls *should* only be made once the original AJAX call is completed; how on earth are the status checks going ahead before the update call is completed?

Driving me nuts.

Help!!
#5

[eluser]Narkboy[/eluser]
Quick update:

I tried swapping the function around, so that it called the status check ajax url, and on success of that, did the update. This made the calls appear correctly in Firebug (i.e backwards - update, then check status, but it didn't actually make a difference to the result.

I also tried all of the various events in the original call; they all caused the status check to go before the update request had completed. Frustrating.

I understand that there is a difference between an ajax request being made successfully, and the web server finishing all the information and sending back a response, but this is silly.

I've missed something obvious, haven't I?
#6

[eluser]Narkboy[/eluser]
Ok. Well - I have a sort-of solution.

If I create a new function:
Code:
function set_status(status) {
            $.ajax( { url: '/admin/cp_ajax/status_change_mode/' + status , dataType: 'html' , cache: false } );
            setTimeout("check_status()" , 1000);
        };

It works. I've checked the changes made by the PHP function and they work immediatly - I can't be certain they take less than a second or two, but it does work for the next page call.

WTF?

The php function that gets called is:
Code:
function update_site_mode($to) {

        // Get the current mode:
        $mode = $this->config->item('site_mode');

        // Make sure that the $to is acceptable:
        if ( $to != 'online' && $to != 'maintenance' && $to != 'testing' ) {
            // Requested mode is not acceptable:
            log_message('error' , 'CT_Local::update_site_mode - bad $to recieved ('.$to.').');

            // Add to the audit trail:
            $this->log_mode_update('Update', $mode, $to, 'Fail - bad mode recieved');

            return FALSE;
        }

        // Hardcode the file:
        $filename = '../htapp/application/config/tgt_config.php';

        if( ! is_really_writable($filename)) {
            // Log an error:
            log_message('error' , 'CT_Local::update_config could not write to the config file.');

            // Add to the audit trail:
            $this->log_mode_update('Update', $mode, $to, 'Fail - config file not writable');
            return FALSE;
        }

        $fh = fopen( $filename , 'r+' );

        if ( ! $fh ) {
            // Log an error:
            log_message('error' , 'CT_Local::update_config could not read the config file.');

            // Add to the audit trail:
            $this->log_mode_update('Update', $mode, $to, 'Fail - could not open the config file');
            return FALSE;
        }

        $contents = fread($fh, filesize($filename));

        // Determine the needle to find from the config:
        $needle = "['site_mode']='$mode';";

        // Set the new version required:
        $new_version ="['site_mode']='$to';";

        $updated = str_replace( $needle , $new_version , $contents);

        // Clear the file:
        ftruncate($fh , 0);
        rewind($fh);

        // Write the new data in:
        fwrite( $fh , trim($updated) );

        // Can we check the new config? Not via $this->config...
        // @todo Way to check the changes were made..

        $this->log_mode_update('Update', $mode, $to, 'Ok');

        // Return:
        return TRUE;
    }

I'm giving up for the night. It's either:

1) a time thing - it takes longer to edit / close the file than the ajax request takes to complete. Weird.
2) a jQuery thing - success requests are sent before they should be. Not really possible.
3) Something else.

Bah.
#7

[eluser]vitoco[/eluser]
ajax call ( unless you set it otherwise ) are async...so order of the returned data depends on the server, when you make

Code:
$('#status_holder').load('/admin/cp_ajax/status_return_status');
      $('#status_actions').load('/admin/cp_ajax/status_return_actions');

both call are made in the "same time"..so the second doesn't wait for the first to finish, to do that use always callbacks

jquery load description

Code:
$('#status_holder').load(
        '/admin/cp_ajax/status_return_status' ,
        {} ,
        function( responseText, textStatus, XMLHttpRequest )
        {
            $('#status_actions').load('/admin/cp_ajax/status_return_actions');
        }
    );

Saludos
#8

[eluser]Narkboy[/eluser]
Yup. Something simple.

Request success != callback. That's where I was going wrong!

Thank you so much!! :lol:




Theme © iAndrew 2016 - Forum software by © MyBB