• Hi,thanks for writing W3TC. It’s pretty awesome.

    However I’ve encountered an issue with varnish cache purging.

    I did the folowing:

    1. enabled varnish purges
    2. set the blog’s domain as a varnish server URL
    3. enabled varnish debugging

    varnishlog and also w3tc’s varnish debugging log show that GET requests have been sent to varnish instead of PURGE.

    Although I am far from being expert on PHP, after looking at the code I noticed that w3tc uses the WP_Http class to send the PURGE requests. The WP_Http class documentation states the following:

    Accepted ‘method’ values are ‘GET’, ‘POST’, and ‘HEAD’, some transports technically allow others, but should not be assumed.

    I’ve searched the web, but haven’t found much information.

    Will this be fixed?

    I currently modified w3-total-cache/lib/W3/Varnish.php like shown below.

    <?php
    
    /**
     * Varnish purge object
     */
    
    /**
     * Class W3_Varnish
     */
    class W3_Varnish {
        /**
         * Debug flag
         *
         * @var bool
         */
        var $_debug = false;
    
        /**
         * Varnish servers
         *
         * @var array
         */
        var $_servers = array();
    
        /**
         * Operation timeout
         *
         * @var int
         */
        var $_timeout = 30;
    
        /**
         * PHP5-style constructor
         */
        function __construct() {
            $config = & w3_instance('W3_Config');
    
            $this->_debug = $config->get_boolean('varnish.debug');
            $this->_servers = $config->get_array('varnish.servers');
            $this->_timeout = $config->get_integer('timelimit.varnish_purge');
        }
    
        /**
         * PHP4-style constructor
         */
        function W3_Varnish() {
            $this->__construct();
        }
    
        /**
         * Purge URI
         *
         * @param string $uri
         * @return boolean
         */
        function purge($uri) {
            require_once W3TC_INC_DIR . '/functions/http.php';
    
            @set_time_limit($this->_timeout);
    
            if (strpos($uri, '/') !== 0) {
                $uri = '/' . $uri;
            }
    
            foreach ((array) $this->_servers as $server) {
                $url = sprintf('http://%s%s', $server, $uri);
    
    	    $ch = curl_init();
    	    curl_setopt($ch, CURLOPT_TIMEOUT, 5);
    	    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2);
    	    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PURGE');
    	    curl_setopt($ch, CURLOPT_URL, $url);
    	    curl_setopt($ch, CURLOPT_USERAGENT, W3TC_POWERED_BY);
    	    curl_exec($ch);
    	    if (!curl_errno($ch)) {
    		$respinfo = curl_getinfo($ch);
    	        $this->_log($url, $respinfo['http_code'] . ' (' . $respinfo['total_time'] . ' sec)');
    	    } else {
    		$this->_log($url, 'Curl error: ' . curl_error($ch));
    	    }
    	    curl_close ($ch);
    	    unset($ch);
    	}
    
            return true;
        }
    
        /**
         * Write log entry
         *
         * @param string $url
         * @param string $error
         * @return bool|int
         */
        function _log($url, $error) {
            if ($this->_debug) {
                $data = sprintf("[%s] [%s] %s\n", date('r'), $url, $error);
    
                return @file_put_contents(W3TC_VARNISH_LOG_FILE, $data, FILE_APPEND);
            }
    
            return true;
        }
    }

    It works, but some PURGE requests take long to complete and time out.

    Thanks for your insight.

    http://wordpress.org/extend/plugins/w3-total-cache/

Viewing 7 replies - 1 through 7 (of 7 total)
  • Plugin Contributor Frederick Townes

    (@fredericktownes)

    Would you like to check out the next release? Related issues here have been addressed.

    Thread Starter George Notaras

    (@gnotaras)

    Hi Frederick. Thanks for your reply.

    I would gladly test the new release, but, unfortunately, I was unable to locate a newer version than 0.9.2.4. Should I directly use the trunk version?

    Thread Starter George Notaras

    (@gnotaras)

    FYI, the code modifications I posted in the first message (using curl to send the PURGE requests) gave me some trouble with unexpected delays in each request to the varnish server.

    I ended up sending the PURGE requests directly through a socket:

    $host = preg_replace('/^http:\/\/([^\/]+)(.*)/i', "$1", get_bloginfo('wpurl'));
    foreach ((array) $this->_servers as $server) {
        $bits = explode(":", $server);
        $server_addr = $bits[0];
        $server_port = $bits[1];
        $timeout = '5';
    
        $vsock = fsockopen($server_addr, $server_port, $errno, $errstr, $timeout);
        //$vsock = fsockopen('127.0.0.1', '80', $errno, $errstr, $timeout);
        if($vsock) {
            $out = "PURGE " . $uri . " HTTP/1.0\r\n";
            $out .= "Host: " . $host . "\r\n";
            $out .= "User-Agent: " . W3TC_POWERED_BY . "\r\n";
            $out .= "Connection: Close\r\n\r\n";
            fwrite($vsock, $out);
            fclose($vsock);
            $this->_log($url, "PURGE http://" . $host . $uri . " (server:" . $server . ")");
        } else {
            $this->_log($url, "Could not connect to server: " . $server);
        }
    }

    This requires to set the varnish server address and port (eg 127.0.0.1:80) in the W3TC settings.

    Plugin Contributor Frederick Townes

    (@fredericktownes)

    Please shoot me an email to check out the next release.

    Thread Starter George Notaras

    (@gnotaras)

    @frederick sorry I missed your reply. Sending you an email right away.

    Has this issue been fixed? I’m using W3TC with Varnish and when I publish or update a post I’m not seeing the changes. Purging the Varnish cache doesn’t help, only if I user terminal to restart the Varnish service (not ideal). Any advice is greatly appreciated!

    omueller

    (@omueller)

    Hello & many thanks for this useful plugin!

    Just a small feature request for the next update: it seems the cache is emptied as soon as somebody creates a new post (post_status = “auto-draft” in the wp_posts table).

    Maybe you could ignore these specific posts until they are completely ready and published ? Otherwise the cache gets emptied pretty often, especially on a busy page with many redactors like on our system.

    Kind regards,
    Olivier

    PS: strangely, it seems all pages are then gone from the cache, even if the plugin only purges /category/(.*), /, /feed and the new post. But simply ignoring auto-draft posts should solve this anyway… 🙂

Viewing 7 replies - 1 through 7 (of 7 total)
  • The topic ‘[Plugin: W3 Total Cache] varnish cache not purged – sends GET requests instead of PURGE’ is closed to new replies.