Skip to content

Instantly share code, notes, and snippets.

@reedstrm
Last active June 15, 2017 20:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save reedstrm/8c7541f2c463ce09ec07a608efb99635 to your computer and use it in GitHub Desktop.
Save reedstrm/8c7541f2c463ce09ec07a608efb99635 to your computer and use it in GitHub Desktop.
Notes on what gets baked when, with what recipe

Baking and Recipes

Baking has become a critical step for publishing - however, it is not planned for it to cause publishing to fail. This is partly due to how long baking may take - much like PDF generation, it can take several hours, if there are external parts, like exercises, that need to be fetched and incorporated into the pages.

This slightly odd situtation (is baking a publish blocker, or not?) comes about partly due to derived copies - publishing a new version of content impacts not only the immediate book, but any book that shares pages with it. It was decided that failure of related books to bake is not a publication blocker, so by extension, it is not for any book. However, we want to be careful to not break existing books by publishing new content, but we cannot test every book that contains a given page.

Selection of Recipe and Fallback

So, we will implement two ways to mitigate this potential problem. First, will we keep track of when and with what recipe a given book successfully baked. This will point to the actual recipe bits - the file used. In order to use a given recipe for more than one book, we are extending the print_style attribute to also select a default recipe. Note that this can be updated independently of re-baking a given book.

When a new version of a book is published, we will attempt to bake it with the recipe specified by the print_style parameter. There will be a table of recipes that are the current recipe for given print style. If baking with that recipe fails, we will then retry baking with the last successful recipe for this book. If that succeeds, we update the webview, but also mark the state as stale_recipe. This way, the new content is available, even if changes in presentation from a new recipe are not. Note that uploading a new default recipe for a given print_style will also put books in this state.

If the print_style parameter value does not have a default recipe associated with it, we will then check to see if a file with that name has been attached to the book. If there is no file, the book will be marked Done/Success. This will allow us to rollout recipes gradually for existing print styles. If there is a file, this will serve as a local recipe for baking a specific book, while removing the need for a "magic filename" from our processing code. The fallback described above would still be used - if the current book doesn't bake, use the most recent sucessful recipe, unless it is the same one we just tried.

Content Fallback

If both attempts to bake fail, we leave the existing baked content in place, and mark the book as stale_content. The latest version of the content will still be available, by viewing the raw version, via the ?baked=false query parameter.

Publishing individual pages causes minor-version revisions of each book that contains that page. This leads to a thundering-herd problem when trying to do several page edits in a row each start a book, and all of its derived copies, to bake. To help resolve this, we will no longer trigger baking on minor version revisions. We instead will mark these books as pending, and process them on a delayed schedule. An interface for directly triggering baking for a given book in the pending state will be provided, but a time-based process will also "sweep up" books in this state. However, only the most recent minor version will be baked - when multiple pages and edited and published, each publish event will set the book with the new minor version to pending, while setting the previously pending minor version to raw_only.

Reporting Baking State

The state of baking of a given book will be available in the /extras page for that book. This will be used to drive additional UI in the More Information tab, where the "Print Style" is currently reported. If the state is pending or stale_recipe, a link to trigger immediate baking will be provided (this is a POST). Also, the most recent history of baking, with error messages, will be available here.

In addition, a global "state of baking" page will give an overview of all books and their current baked state. Again, any that are not current will have links available to attempt rebaking.

------ old notes

What about re-baking? What conditions would trigger a need to rebake w/o republishing content? 1 - change to cxnml-> HTML transforms 2 - change in recipe

Before I go implement the error-thrower, I should say - one of the design goals behind the existing Oven class was that it never error on baking - I suppose it does need to be able to handle some sort of error return for not-parsable-input - but if the CSS is CSS, and the HTML is an HTML tree, I expect to get no error. Currently, the oven.bake() method works directly on a tree, and returns nothing. That could be changed to return some object that reports on what rules were applied. Hmm, I see because of how tinycss2's parser works (basically the same - it doesn't throw errors, it returns an parseerror object), I'm effectively ignoring CSS parse errors as well. Not good. O.k. we need some work here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment