(function ($) {

  "use strict";

  $(document).ready(function() {
    var nid = Drupal.settings.statistics.nid;
    var basePath = Drupal.settings.basePath;
    $.ajax({
      type: "POST",
      cache: false,
      url: basePath+"core/modules/statistics/statistics.php",
      data: "nid="+nid
    });
  });
})(jQuery);

1. This is slow down the stat record.

  $(document).ready(function() {

2. missing error handler.

(3. GET method is better in performance)

Comments

nod_’s picture

1. Need the ready since you can't be sure Drupal.settings will be properly populated before the ready event (that bit me a few times).
2. I'm not sure how useful the error handler would be, what do you mean? You want a way to specify an error handler, is that it?
(3. POST won't have cache issues in case some proxy in the middle is caching GET requests.)

droplet’s picture

1. It can be inline code after Drupal.settings (or add a onContentReady function)
2. It should retry when request to statistics.php is failed.

nod_’s picture

makes sense, why not.

valthebald’s picture

StatusFileSize
new2.92 KB

I made the following changes:
1. Changed request type to get and added timestamp parameter to avoid cached by malformed proxies
2. made "use strict" global
3. made statistics.php a variable populated during page load
4. changed ready event to be jquery ready. Drupal.settings is ready at that moment.
5. added basic error handling. So far it checks for response code, and I think there's no reason to retry if we have server-related problems (4xx/5xx)

nod_’s picture

Status: Active » Needs work

+ddd ? shouldn't be here.

I'm not sure about the amount of changes in here, seems less readable than before.

valthebald’s picture

Status: Needs work » Active
StatusFileSize
new2.88 KB

By the way, I think ts parameter is not necessary, since jQuery adds it's '_' parameter, so probably we can just skip that

valthebald’s picture

yes, sure about ddd - placed this in statistics.php to simulate server error, and submitted by mistake

valthebald’s picture

Status: Active » Needs review
StatusFileSize
new2.83 KB

Switched back to the syntax found in other D8 JavaScript files.

valthebald’s picture

StatusFileSize
new2.92 KB

And... slightly more readable indents

Status: Needs review » Needs work

The last submitted patch, 1684968-9.patch, failed testing.

valthebald’s picture

Tests fail, since there are 2 writes to database during AJAX call - in page handler and in hook_exit()
I'm new in D8, so please excuse me: what's the "standard" way to determine execution context in hook_exit()?
(i.e. what's the current menu_item, or if statistics was already called etc.)

As an alternative, maybe it's possible to add another setting to the settings form - either to use AJAX for statistics or traditional hook_exit(). I see no reason to use both methods simultaneously

nod_’s picture

tag

valthebald’s picture

Status: Needs work » Needs review
StatusFileSize
new11.99 KB
  1. Changed tests to issue GET requests
  2. Added error handler to $.ajax() call

Status: Needs review » Needs work

The last submitted patch, 1684968-13.patch, failed testing.

valthebald’s picture

Status: Needs work » Needs review
StatusFileSize
new13.22 KB

Turns out search tests also call statistics.php, fixed failing test.
(By the way, isn't that a sign of unneeded intimacy between 2 modules? Shouldn't search module call API function of statistics module instead?)

nod_’s picture

#15: 1684968-15.patch queued for re-testing.

Status: Needs review » Needs work

The last submitted patch, 1684968-15.patch, failed testing.

jhodgdon’s picture

Found this issue... I'm actually working on that search module test right now so maybe you can remove it from this issue. And that section of the search module test is not working anyway due to #893302: Search ranking based on the factor "number of comments" & "No of Page Views" is broken

So in comment #15, you suggest that a statistics API call should be used instead of trying to simulate viewing the node. I looked in statistics.module and did not see any API function to call... Can you enlighten me? And meanwhile I'll try taking the modifications you made to the search test over to that other issue.

jhodgdon’s picture

Actually, I can't really try that patch, as it looks like statistics.php is using POST not GET... not sure what to do.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

wim leers’s picture

Issue summary: View changes
Status: Needs work » Needs review
Issue tags: +JavaScript
StatusFileSize
new1.95 KB
  1. Switching to a GET request seems pointless. There's no performance benefit at all. Instead you now have to work around HTTP semantics.
  2. +++ b/core/modules/statistics/statistics.js
    @@ -2,14 +2,19 @@
    -  $(document).ready(function() {
    ...
    +  Drupal.stats = function(){
    ...
    +      error: function(jqXHR, textStatus, errorThrown){
    +       if(jqXHR.status<400){
    +        window.setTimeout(Drupal.stats, Drupal.settings.statistics.retry);
    +       }
    +      }
    ...
    +  Drupal.stats();
    

    These are the truly essential bits … except that It can be inline code after Drupal.settings (or add a onContentReady function) is neither implemented nor sensible to implement — it'd require us to move JS code for the Statistics module in the base module.

  3. +++ b/core/modules/statistics/statistics.module
    @@ -104,7 +104,13 @@ function statistics_permission() {
    +      'logger' => base_path() . drupal_get_path('module', 'statistics') . '/statistics.php',
    

    This is already implemented in HEAD.

  4. +++ b/core/modules/statistics/statistics.module
    @@ -104,7 +104,13 @@ function statistics_permission() {
    +      // Timeout between logging attempts, in milliseconds.
    +      // @todo: add this to settings screen?
    +      'retry' => 100,
    

    There's no point in making this configurable (who's ever going to customize it?), it just means more data to send with every HTML response.

AFAICT that means there's basically nothing else to be done here. The only thing this would gain, is retries.


+++ b/core/modules/statistics/statistics.js
@@ -2,14 +2,19 @@
+       if(jqXHR.status<400){
+        window.setTimeout(Drupal.stats, Drupal.settings.statistics.retry);
+       }

Retrying after a <400 response makes no sense. <400 implies 2xx or 3xx. 3xx is a redirect, which browsers would automatically follow. 2xx would mean it'd have succeeded.

Implemented just the retrying, and made it much simpler.

borisson_’s picture

Is it possible, or even needed to write a test for this? Basically overwrite drupalSettings.statistics.url to a new controller that implements something like a this and extends statistics.php for the rest of the code.

if (!$_COOKIE['already_visited_statistics']) {
setcookie('already_visited_statistics', TRUE);
sleep(5);
}

include 'statistics.php';

I love how much simpler #25 is compared to the previous approaches, great work Wim!

GrandmaGlassesRopeMan’s picture

Version: 8.5.x-dev » 8.6.x-dev
StatusFileSize
new1.75 KB
new852 bytes

- clean up code-style issues.

wim leers’s picture

Title: More reliable statistics.js » More reliable statistics.js: retry after 2 s when request fails

Clarifying issue title.

I'm also not sure about the need for explicit test coverage for this, it seems overkill.

@drpal, thoughts?

GrandmaGlassesRopeMan’s picture

@Wim Leers The only thing I could think of would be to ensure that the request will retry after 2 seconds, however that is probably not needed since that behavior is part of jQuery.

borisson_’s picture

Status: Needs review » Reviewed & tested by the community

Ok, I was doutbful about if such a test was useful anyway, setting to RTBC based on @drpal's feedback.

dawehner’s picture

I'm not 100% convinced about this fix.
Let's assume someone would have configured the webserver to just have index.php as single front controller (This is security best practise), and then you decide to ship with statistics module on your website.

As your dev environment is not your life environment you start hitting your main index.php with this statistics script, and you end up increasing your load by 5x.

Possible solutions:

GrandmaGlassesRopeMan’s picture

Status: Reviewed & tested by the community » Needs review
StatusFileSize
new2.45 KB
new1.72 KB
pancho’s picture

@dawehner: Yes, I agree we shouldn‘t retry every 2 seconds indefinitely.

An exponential or maybe cubic growth function seems to be the best fit in every respect. This way we could, IMHO should, even start with an interval considerably smaller than 2s.

dawehner’s picture

+++ b/core/modules/statistics/statistics.es6.js
@@ -11,8 +11,18 @@
+            this.retryDelay = this.retryDelay * (2 * 1000);

Wait, so we increase it from 1 to 2000 to 4000000, this feels quite a steep increase.

GrandmaGlassesRopeMan’s picture

StatusFileSize
new812 bytes
new2.44 KB

📈 does seem a bit excessive. This dials it back to 2, 4, and 8 seconds.

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

Thank you @drpal for the quick iteration cycle!

pancho’s picture

True, let’s try it this way. RTBC.

wim leers’s picture

Nice, @drpal, and great remark, @dawehner!

alexpott’s picture

Status: Reviewed & tested by the community » Needs review

Should we implement backoff as per Google's suggestion? See https://developers.google.com/analytics/devguides/reporting/core/v3/erro...

Also a standard way of backing off feels useful rather than coding something special for statistics

dawehner’s picture

Ah, so we are almost implementing what google suggests :)
Do we understand the random amount of milliseconds bit? (I guess this ensures equal distribution of requests to the server)

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: -JavaScript +JavaScript, +Needs Review Queue Initiative

This issue is being reviewed by the kind folks in Slack, #need-reveiw-queue. We are working to keep the size of Needs Review queue [2700+ issues] to around 400 (1 month or less), following Review a patch or merge require as a guide.

At this time we would need a D10.1.x patch or MR for this issue.

_utsavsharma’s picture

Status: Needs work » Needs review
StatusFileSize
new1.22 KB
new1.22 KB

Patch for 10.1.x.
Please review.

alexpott’s picture

Status: Needs review » Needs work

I think this is very nearly ready - we should be adding in some jitter as described in https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/ - I also think we should be adding a follow-up to generalise this type of functionality as it is useful.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

quietone’s picture

Project: Drupal core » Statistics
Version: 11.x-dev » 1.0.0-beta1
Component: statistics.module » Code