Skip to content
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

Don't request all the blocks for liveblog main page #13566

Merged
merged 16 commits into from
Jul 18, 2016
Merged

Conversation

johnduffell
Copy link
Member

@johnduffell johnduffell commented Jul 12, 2016

This PR changes the CAPI query for liveblog page 1 (the live page) and the ajax "get updates" call to only retrieve the necessary blocks, rather than the whole liveblog.

This should save a lot of bandwidth as liveblogs get bigger, and also reduce the CPU usage both in CAPI and frontend. We noticed things were particularly bad when there were many big liveblogs running after brexit. This is a problem particularly for those two endpoints because they only have a 5 second cache time. Archive pages of a live blog cache for a few minutes.

This is part 2 of the series - part 1 was #13458

@TBonnin @cb372 @JustinPinner any comments or +1s please!

def withParser: Parser[Unit] = "with:" ^^ { _ => () }
def block: Parser[Unit] = "block-" ^^ { _ => () }
def id: Parser[String] = "[a-zA-Z0-9]+".r
def blockId = block ~> id
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to make those private if they are not supposed to be exposed outside of this object?

@TBonnin
Copy link
Contributor

TBonnin commented Jul 13, 2016

Thanks for doing this @johnduffell
A lot of going on in this PR. I would be happy if more people are reviewing it.

@johnduffell
Copy link
Member Author

johnduffell commented Jul 13, 2016

thanks for picking through that one @TBonnin it can't have been fun, and more reviews are better. I did a lot of things I wasn't 100% happy with the result, I feel like the code ended up slightly more complicated in the end. I've done the updates you suggested, thanks

@cb372
Copy link
Contributor

cb372 commented Jul 13, 2016

I'm going to take a look at it now.

@@ -167,7 +194,7 @@ class ArticleController extends Controller with RendersItemResponse with Logging
.showReferences("all")
.showAtoms("all")

val capiItemWithBlocks = if (blocks) capiItem.showBlocks("body") else capiItem
val capiItemWithBlocks = range.map(r => capiItem.showBlocks(r.query.map(_.mkString(",")).getOrElse("body"))).getOrElse(capiItem)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe split this line up for readability?

@cb372
Copy link
Contributor

cb372 commented Jul 13, 2016

Good stuff! I hope all this work pays off in bandwidth savings!

I'm going to work this afternoon on adding the support for "blocks created/modified since" that we discussed.

@johnduffell
Copy link
Member Author

ok I've managed to get the tests passing, can anyone take a look and give me a +1 please? Next stage after this is to increase the cache time for "updates since block X" requests where block X isn't the latest block. That should leave only one html page and one json page with a 5 second cache time

@johnduffell
Copy link
Member Author

after that change all the perf updates should be complete, then I can start making it use published-since to get edits as well as new blocks and also fix the timeline to update again.

@TBonnin
Copy link
Contributor

TBonnin commented Jul 15, 2016

👍 thank you very much @johnduffell

# Conflicts:
#	article/app/controllers/ArticleController.scala
@johnduffell johnduffell merged commit a8b26fa into master Jul 18, 2016
@johnduffell johnduffell deleted the liveblog-blocks branch July 18, 2016 08:47
rtyley added a commit that referenced this pull request Aug 3, 2022
`LiveBlogCurrentPage.findPageWithBlock()` is responsible for making sure
that when a user clicks on a live-blog permalink to a **block**, eg:

https://www.theguardian.com/politics/live/2022/aug/01/tory-leadership-race-rishi-sunak-lizz-truss-vote-keir-starmer-uk-politics-live?page=with:block-62e7e89d8f08730a1f7f5579#block-62e7e89d8f08730a1f7f5579

...the user is taken to the correct 'page' of the live blog - page 3 of 5
in the example above, for instance. The code was was first introduced in
January 2016 with #11700,
subsequently updated with #13566,
etc.

The existing code compiles without warnings under Scala 2.12, but the
Scala 2.13 compiler gives a warning that not _all_ conceivable cases
in the pattern-match are handled:

```
frontend/common/app/model/LiveBlogCurrentPage.scala:190:12: match may not be exhaustive.
[warn] It would fail on the following inputs: List(_), Nil
[warn]       .map {
[warn]            ^
```

In this particular case, the warning's unnecessary - the preceding `.sliding(3)`:

https://github.com/guardian/frontend/blob/f90c8a58e6f0941c96392d14fe27e61a4dbaf25b/common/app/model/LiveBlogCurrentPage.scala#L188

...means that the List supplied to the case match expression will
_always_ have 3 elements, and that's precisely the case that's handled -
but there's no way for the compiler to know that - so we as devs need to
do _something_ to make the warning go away!

See also:

* The Scala 2.13 upgrade PR: #25190
rtyley added a commit that referenced this pull request Aug 3, 2022
`LiveBlogCurrentPage.findPageWithBlock()` is responsible for making sure
that when a user clicks on a live-blog permalink to a **block**, eg:

https://www.theguardian.com/politics/live/2022/aug/01/tory-leadership-race-rishi-sunak-lizz-truss-vote-keir-starmer-uk-politics-live?page=with:block-62e7e89d8f08730a1f7f5579#block-62e7e89d8f08730a1f7f5579

...the user is taken to the correct 'page' of the live blog - page 3 of 5
in the example above, for instance. The code was was first introduced in
January 2016 with #11700,
subsequently updated with #13566,
etc.

The existing code compiles without warnings under Scala 2.12, but the
Scala 2.13 compiler gives a warning that not _all_ conceivable cases
in the pattern-match are handled:

```
frontend/common/app/model/LiveBlogCurrentPage.scala:190:12: match may not be exhaustive.
[warn] It would fail on the following inputs: List(_), Nil
[warn]       .map {
[warn]            ^
```

In this particular case, the warning's unnecessary - the preceding `.sliding(3)`:

https://github.com/guardian/frontend/blob/f90c8a58e6f0941c96392d14fe27e61a4dbaf25b/common/app/model/LiveBlogCurrentPage.scala#L188

...means that the `List` supplied to the case match expression will
_always_ have 3 elements, and that's precisely the case that is handled -
but there's no way for the compiler to know that - so we as devs need to
do _something_ to make the warning go away!

Some options:

* Use the @unchecked annotation (see https://www.scala-lang.org/api/2.12.7/scala/unchecked.html)
  This is an option of last resort - turning off compiler checks leaves us
  exposed to runtime errors and is generally a bad idea!
* Use `collect()` rather than `map()` - this accepts a partial function,
  rather than a total one, so the compiler error will go away.
  https://www.scala-lang.org/api/2.12.7/scala/collection/immutable/Seq.html#collectFirst[B](pf:PartialFunction[A,B]):Option[B]
* Refactor so that the code no longer needs to assume that a `List` type
  (which can have any length) has length `3`.

In the end I decided to go with the refactor, because there were a few
things about the existing code that could be tweaked:

* Unnecessary work: The method was creating a `LiveBlogCurrentPage` for
  _every_ page in the liveblog, even though it only ever needed one
  (the single page that the block actually exists on!), and would
  eventually throw away the rest.
* The logic around padding the front & end of the `pages` List with
  two `None` entries, to allow extracting the `newer` & `older` pages,
  totally worked but added an extra step to the code (and therefore a
  bit of complexity for humans to understand: "what are endedPages?")
  and could be replaced by just incrementing/decrementing the page index
  for the one `LiveBlogCurrentPage` we're now creating.
* Various variables could be inlined to the point of creation on the
  `LiveBlogCurrentPage` case class. By using named parameters in constructing
  the case class, no clarity is lost, and the code is more concise.

See also:

* The Scala 2.13 upgrade PR: #25190
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

Successfully merging this pull request may close these issues.

4 participants