solidusjs / solidus

A simple server that generates pages from JSON and Templates
MIT License
28 stars 7 forks source link

Preview mode #133

Closed pushred closed 8 years ago

pushred commented 8 years ago

Background resource fetching has definitely helped with resource timeouts we were previously experiencing. But an unfortunate side effect has been added time required to reliably publish content. CDN caches and servers running in multiple regions exacerbate the problem with regional inconsistencies in published content. Without any insight into the inner workings of Solidus and storyteller.io they are left refreshing and checking periodically for 10-20 minutes in an effort to get their content live. This is an understandably frustrating distraction in their workflow.

Fixing this problem in production will be challenging, if a site is served by a CDN it will always add a delay of some length. We must also encourage caching of pages served to limit resource requests. Accessing the origin server directly avoids the CDN delays. But page caching retains a significant delay of up to 5 minutes. The development mode disables page caching, but two refreshes are still unintuitively required to see new content. Content authors need a way to reliably see the latest content after saving it, just like the typical CMS experience they are accustomed to.

To accomplish this I propose a preview mode that:

This could be enabled with another server option but that would require running a separate server that's kept consistent with whatever is in production. A separate subdomain that triggers this behavior on page requests whenever the hostname matches would avoid those complications. preview.example.com for instance could be set as a secondary domain on existing production instances, also being an easy to remember URL for bypassing the CDN.

localjo commented 8 years ago

I think the biggest hangup right now isn't in the Solidus layer, but in the fact that resources are being proxied in a way that Solidus doesn't have direct access to the origin resource. To clarify what you're talking about here; are you proposing this in addition to other features in Storyteller, etc that would also bypass caching?

What about adding a resource key in addition to the URL that looks like this?

...
  "resources": {
    "doges": {
      "url": "https://proxy.com/api/v2/resources/4521zb/such-doges",
      "origin": "https://example.com/api/v2/resources/4521zb/such-doges"
    }
  }
...

And when a "preview mode" is triggered, Solidus fetches the origin resource on each request.

localjo commented 8 years ago

Another idea (which may not be realistic to implement, but I'll mention it anyway), might be to structure Storyteller responses with an origin key, something like this;

{
  "origin": "https://example.com/api/v2/resources/4521zb/such-doges",
  "response": // cached endpoint response here
}
pushred commented 8 years ago

Well the caching I'm actually trying to get around here is the CDN and rendered pages. What you're touching on is the storyteller.io cache which would still apply even if we could disable background resource fetching here. The solution there is a storyteller.io feature in the works that enables a "passthrough" mode when a certain header is applied to requests, giving us the auth and normalization benefits of storyteller.io that keeps config light on the sites while bringing latency down to a minimum.

This will require one more addition to the list for this preview mode, some refinement to auth.json for applying that header to the pertinent requests. Perhaps we optionally support environment/mode blocks of configuration in that file:

{
  "http://proxy.storyteller.io/*": {
    "headers": {
      "Api-Key": "0000aaaa-aa00-00aa-a00a-aaaa000000"
    }
  },
  "http://services.sparkart.net/*": {
    "query": {
      "key": "1111bbbb-bb11-11bb-b11b-bbbb111111"
    }
  },
  "preview": {
    "http://proxy.storyteller.io/*": {
      "headers": {
        "Passthrough": "example"
      }
    }
  }
}

Where the contents of the blocks would add or override anything set at the base.

My hope is that the latest content can be fetched and displayed (hopefully) in the same request, enabling the refresh-to-preview behavior content authors expect.

joanniclaborde commented 8 years ago

We could also set the 'X-Robots-Tag': 'noindex, nofollow' header in preview mode, in case Google finds its way in there.