Thanks to visit codestin.com
Credit goes to github.com

Skip to content

refreshPath has no effect with Symfony3.2 & FOSRestBundle #362

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
websirnik opened this issue Apr 3, 2017 · 5 comments
Closed

refreshPath has no effect with Symfony3.2 & FOSRestBundle #362

websirnik opened this issue Apr 3, 2017 · 5 comments

Comments

@websirnik
Copy link

I'm using Symfony HttpCache. In my case when I call $this->get('fos_http_cache.cache_manager')->refreshPath('/api/post/xyz') or invalidatePath()my cache does not get refreshed / cleared.

I can see that $this->get('fos_http_cache.cache_manager')->flush() does execute the correct GET request, but the cache still serves the old response.

I'm not sure about the root cause. Please help me debug this. Here is my configs that might be relevant.

Active packages:

"require": {        
    "friendsofsymfony/http-cache-bundle": "^2.0.0-alpha1",
    "friendsofsymfony/http-cache": "^2.0.0-beta1",     
    "friendsofsymfony/rest-bundle": "~2.1.0",  
    "guzzlehttp/guzzle": "~6.0",
    "guzzlehttp/psr7": "^1.4",
    "symfony/symfony": "~3.2.0"
}

config.yml:

fos_http_cache:
    invalidation:
        enabled: true
    proxy_client:
        symfony:
            http:
                servers:
                    - example.dev
                base_url: example.dev

AppCache.php:

<?php

require_once __DIR__ . '/AppKernel.php';

use FOS\HttpCache\SymfonyCache\CacheInvalidation;
use FOS\HttpCache\SymfonyCache\EventDispatchingHttpCache;
use Symfony\Bundle\FrameworkBundle\HttpCache\HttpCache;
use Symfony\Component\HttpFoundation\Request;

class AppCache extends HttpCache implements CacheInvalidation {
	use EventDispatchingHttpCache;

	/**
	 * Made public to allow event listeners to do refresh operations.
	 *
	 * {@inheritDoc}
	 */
	public function fetch(Request $request, $catch = false) {
		return parent::fetch($request, $catch);
	}
}

Controller action that sets cache properties:

/**
 * [GET] /api/post/{slug}
 */
public function getPostAction($slug) {

	// ...
	// Getting $post  { .. }
	// ...

	$response = new Response();

	$response->setPublic();
	$response->setSharedMaxAge(86400);

	$view = $this->view($post);
	$view->setResponse($response);

	return $this->handleView($view);
}
@dbu
Copy link
Contributor

dbu commented Apr 3, 2017

just a wild guess: could it be that you are hit by #351? though symfony/symfony#21582 is supposedly in 3.2.5. so unless you ended up with an older version of symfony/symfony this should be fixed...

i suggest you add additional logging in the symfony kernel to see whether the request really is received and works out. try to send an invalidation request with the command line curl to isolate whether the problem is in the application not sending the request or the kernel not correctly handling it. or could the request go to the wrong server/port somehow?

@websirnik
Copy link
Author

Hm, still not sure what's happening. Same behaviour from command line. Requests are going to the right server. I'm on the Symfony 3.2.6.

i suggest you add additional logging in the symfony kernel to see whether the request really is received and works out.

Don't know how to log that.

My feeling that it might be my config issue, but not sure where to look.
I've managed to get invalidatePath() to work, by adding invalidate() to AppCache.php from Symfony docs(see below). refreshPath() still does not refresh the cache. It used to work for me with FOSHttpCacheBundle 1.* , Symfony 2.* , FOSRestBundle 1.* , PHP 5.6. But after the major dependency updates, it just stopped.

<?php

require_once __DIR__ . '/AppKernel.php';

use FOS\HttpCache\SymfonyCache\CacheInvalidation;
use FOS\HttpCache\SymfonyCache\EventDispatchingHttpCache;
use Symfony\Bundle\FrameworkBundle\HttpCache\HttpCache;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class AppCache extends HttpCache implements CacheInvalidation {
	use EventDispatchingHttpCache;

	/**
	 * Made public to allow event listeners to do refresh operations.
	 *
	 * {@inheritDoc}
	 */
	public function fetch(Request $request, $catch = false) {
		return parent::fetch($request, $catch);
	}

	protected function invalidate(Request $request, $catch = false) {
		if ('PURGE' !== $request->getMethod()) {
			return parent::invalidate($request, $catch);
		}

		$response = new Response();
		if ($this->getStore()->purge($request->getUri())) {
			$response->setStatusCode(200, 'Purged');
		} else {
			$response->setStatusCode(404, 'Not found');
		}

		return $response;
	}
}

@dbu
Copy link
Contributor

dbu commented Apr 4, 2017

are you adding the necessary event listeners? https://github.com/FriendsOfSymfony/FOSHttpCache/blob/master/tests/Functional/Fixtures/Symfony/AppCache.php

i fear that the documentation on the bundle could be outdated for this...

@websirnik
Copy link
Author

I've just added the listeners, but still this call $this->get('fos_http_cache.cache_manager')->refreshPath('/api/post/xyz')->flush() does not update the cache, though I can see that Guzzle does do the GET request to example.dev/api/post/xyz.

<?php

require_once __DIR__ . '/AppKernel.php';

use FOS\HttpCache\SymfonyCache\CacheInvalidation;
use FOS\HttpCache\SymfonyCache\DebugListener;
use FOS\HttpCache\SymfonyCache\EventDispatchingHttpCache;
use FOS\HttpCache\SymfonyCache\RefreshListener;
use Symfony\Bundle\FrameworkBundle\HttpCache\HttpCache;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\HttpKernelInterface;

class AppCache extends HttpCache implements CacheInvalidation {
	use EventDispatchingHttpCache;

	public function __construct(HttpKernelInterface $kernel) {

		parent::__construct($kernel, $kernel->getCacheDir() . '/http_cache', null, null);

		$this->addSubscriber(new RefreshListener());
		
		if (isset($options['debug']) && $options['debug']) {
			$this->addSubscriber(new DebugListener());
		}
	}

	/**
	 * Made public to allow event listeners to do refresh operations.
	 *
	 * {@inheritDoc}
	 */
	public function fetch(Request $request, $catch = false) {
		return parent::fetch($request, $catch);
	}
}

@dbu
Copy link
Contributor

dbu commented Apr 6, 2017

do you see the request arriving at the webserver? you could either build something into the AppCache (or the plugin from us) to write log messages to a tmp file or whatever, just so you see if it happens. also, try to do a curl request with a refresh to see if the problem is in the cache or in sending the invalidation request. i can't debug that for you.

btw, if you run the php built-in webserver and invalidate from a web request, there will be problems (usually a timeout) because the built-in webserver is single threaded.

@dbu dbu closed this as completed Apr 24, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants