Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Code Spelunking: Teach Yourself How Rails Works

Code Spelunking: Teach Yourself How Rails Works

Have you ever wondered how something works deep in the guts of Rails or been stuck when a README says one thing but the code acts another way? Guides and docs are often the best way to get started but when they fall short, you may need to get your hands dirty.

Using method introspection, this talk will show you ways to confidently explore Rails code. By looking at common problems inspired by real-world situations, learn how to dive into Rails and teach yourself how any feature works under-the-hood.

Let’s go spelunking!

2c10bda8a39a60ab149e4e4ccde3e365?s=128

Jordan Raine

May 02, 2019
Tweet

Transcript

  1. @jnraine Code spelunking teach yourself how Rails works

  2. Jordan Raine @jnraine Vancouver, Canada

  3. None
  4. I’m STUCK

  5. None
  6. <?php require( dirname(__FILE__) . '/db-config.php' ); $connection = connect_to_database($db_user, $db_password);

    $post = $connection->query("SELECT * FROM posts WHERE slug = '%".$_SLUG."%';"); ?> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <?php require( dirname(__FILE__) . '/head.php' ); ?> <body> <h1><?php $post["title"]; ?></h1> <div class="content"> <?php $post["body"]; ?> </div> </body> <?php require( dirname(__FILE__) . '/footer.php' ); ?> </html>
  7. None
  8. None
  9. None
  10. I’m STUCK

  11. How you spend your time

  12. Measuring Program Comprehension A Large-Scale Field Study with Professionals Xin

    Xia , Lingfeng Bao, David Lo , Zhenchang Xing, Ahmed E. Hassan, and Shanping Li Published 30 July 2017 ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ ̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉̉ *
  13. 78 developers 2 companies 3,148 working hours

  14. Comprehension Other Editing Navigation

  15. Comprehension & Navigation Other Editing

  16. Average Percentage of Time Spent by Developers 0% 25% 50%

    75% 100% Comprehension
 & Navigation Editing Other 82% 5% 13%
  17. Average Percentage of Time Spent by Developers 0% 25% 50%

    75% 100% Comprehension
 & Navigation Editing Other 82% 5% 13%
  18. Average Percentage of Time Spent by Developers 0% 25% 50%

    75% 100% Comprehension
 & Navigation Editing Other 82% 5% 13%
  19. No comments or insufficient comments Meaningless classes/methods/variable names Large number

    of LOC in a class/method Inconsistent coding styles Lack of documentation, ambiguous requirements Unfamiliarity with business logic Query refinement, browsing a number of search results Navigating inheritance hierarchies Many third-party libraries Poor IDE support for code navigation Switching between editor/IDE and browser
  20. 1. Write code that is easier to use and change

    2. Improve our ability to find answers future you you
  21. The more experience someone had, the less time they spent

    on program comprehension.
  22. How you spend your time Obstacles

  23. None
  24. Rails is big

  25. $ rails new blog ! " 77 gems >250k LOC

    12 core gems 75k LOC How this was calculated: https://gist.github.com/jnraine/b0f7bb5a4a5b10ff07274389e2de83ad
  26. Rails is complex

  27. ActionController::Base.ancestors.count # => 65 ActiveRecord::Base.ancestors.count # => 67

  28. Post.new.save super super super

  29. Rails is magic

  30. define_method "#{callback}_action" do |*names, &blk| _insert_callbacks(names, blk) do |name, options|

    set_callback(:process_action, callback, name, options) end end
  31. %w{ Symbol Slash Dot }.each do |t| class_eval <<-eoruby, __FILE__,

    __LINE__ + 1 class #{t} < Terminal; def type; :#{t.upcase}; end end eoruby end
  32. Rails isn’t your codebase

  33. How you spend your time Obstacles Code Spelunking

  34. None
  35. 1. Ask a question 2. Start with what you know

    3. Only read relevant code
  36. What’s the difference between try and try!?

  37. What’s the difference between try and try!? $ rails c

    Loading development environment (Rails 6.0.0) >> "something".length => 9 >> nil.length NoMethodError: undefined method `length' for nil:NilClass
  38. What’s the difference between try and try!? >> "something".try(:length) =>

    9 >> nil.try(:length) => nil
  39. try(:length) try!(:length) "something" 9 9 nil nil nil What’s the

    difference between try and try!? >> "something".try!(:length) => 9 >> nil.try!(:length) => nil
  40. try(:length) try!(:length) "something" 9 9 nil nil nil What’s the

    difference between try and try!? >> "something".try!(:length)
  41. None
  42. Method Introspection

  43. try(:length) try!(:length) "something" 9 9 nil nil nil What’s the

    difference between try and try!? >> "something".try!(:length)
  44. # dog.rb class Dog def name "Foxley" end def good_boy?

    true end end
  45. >> Dog.new.methods

  46. >> Dog.new.methods =>[:good_boy?, :name, :to_json, :deep_dup, :acts_like?, :html_safe?, :w ith_options,

    :duplicable?, :blank?, :present?, :presence, :to_yaml, :as _json, :instance_values, :instance_variable_names, :in?, :to_param, :pr esence_in, :to_query, :pretty_print_cycle, :pretty_print_instance_varia bles, :pretty_print, :pretty_print_inspect, :try, :try!, :require_or_lo ad, :load_dependency, :unloadable, :instance_variable_defined?, :remove _instance_variable, :instance_of?, :kind_of?, :is_a?, :tap, :instance_v ariable_get, :instance_variable_set, :protected_methods, :instance_vari ables, :private_methods, :method, :public_method, :public_send, :single ton_method, :define_singleton_method, :class_eval, :pretty_inspect, :ex tend, :to_enum, :enum_for, :<=>, :===, :=~, :! ~, :gem, :eql?, :respond_to?, :byebug, :remote_byebug, :debugger, :free ze, :inspect, :object_id, :send, :to_s, :display, :class, :nil?, :hash, :dup, :singleton_class, :clone, :then, :itself, :yield_self, :untaint, :taint, :tainted?, :trust, :untrust, :untrusted?, :singleton_methods, : frozen?, :methods, :public_methods, :equal?, :!, :==, :instance_exec, :
  47. >> Dog.new.methods - Object.new.methods

  48. >> Dog.new.methods - Object.new.methods => [:good_boy?, :name]

  49. >> Dog.new.methods.grep /instance/

  50. >> Dog.new.methods.grep /instance/ => [:instance_values, :instance_variable_names, :pretty_print_instance_variables, :instance_variable_defined?, :remove_instance_variable, :instance_of?,

    :instance_variable_get, :instance_variable_set, :instance_variables, :instance_exec, :instance_eval]
  51. >> dog = Dog.new => #<Dog:0x00007fedbe85ba48> >> dog.method(:name) => #<Method:

    Dog#name> >> dog.method(:name).source_location => ["/spelunking/app/models/dog.rb", 2]
  52. >> dog = Dog.new => #<Dog:0x00007fedbe85ba48> >> dog.method(:name) => #<Method:

    Dog#name> >> dog.method(:name).source_location => ["/spelunking/app/models/dog.rb", 2] >> dog.method(:name).source
  53. >> dog = Dog.new => #<Dog:0x00007fedbe85ba48> >> dog.method(:name) => #<Method:

    Dog#name> >> dog.method(:name).source_location => ["/spelunking/app/models/dog.rb", 2] >> dog.method(:name).source ! gem “method_source”
  54. >> dog = Dog.new => #<Dog:0x00007fedbe85ba48> >> dog.method(:name) => #<Method:

    Dog#name> >> dog.method(:name).source_location => ["/spelunking/app/models/dog.rb", 2] >> dog.method(:name).source => " def name\n \”Foxley\"\n end\n"
  55. >> dog = Dog.new => #<Dog:0x00007fedbe85ba48> >> dog.method(:name) => #<Method:

    Dog#name> >> dog.method(:name).source_location => ["/spelunking/app/models/dog.rb", 2] >> dog.method(:name).source => " def name\n \”Foxley\"\n end\n" >> dog.method(:name).source.display def name “Foxley" end => nil
  56. >> Post.create(title: "Code spelunking") >> Post.method(:create).source.display def create(attributes = nil,

    &block) if attributes.is_a?(Array) attributes.collect { |attr| create(attr, &block) } else object = new(attributes, &block) object.save object end end => nil
  57. >> Post.create(title: "Code spelunking") >> Post.method(:create).source.display def create(attributes = nil,

    &block) if attributes.is_a?(Array) attributes.collect { |attr| create(attr, &block) } else object = new(attributes, &block) object.save object end end => nil
  58. >> Post.new.save

  59. >> Post.new.save Post.new.save super super super

  60. >> Post.new.save >> Post.new.method(:save)

  61. >> Post.new.save >> Post.new.method(:save) => #<Method: ActiveRecord::Suppressor#save> >> ✅

  62. >> Post.new.save >> Post.new.method(:save) => #<Method: ActiveRecord::Suppressor#save> >> Post.new.method(:save).super_method ✅

  63. >> Post.new.save >> Post.new.method(:save) => #<Method: ActiveRecord::Suppressor#save> >> Post.new.method(:save).super_method =>

    #<Method: ActiveRecord::Transactions#save> >> ✅ ✅
  64. >> Post.new.save >> Post.new.method(:save) => #<Method: ActiveRecord::Suppressor#save> >> Post.new.method(:save).super_method =>

    #<Method: ActiveRecord::Transactions#save> >> Post.new.method(:save).super_method.super_method ✅ ✅
  65. >> Post.new.save >> Post.new.method(:save) => #<Method: ActiveRecord::Suppressor#save> >> Post.new.method(:save).super_method =>

    #<Method: ActiveRecord::Transactions#save> >> Post.new.method(:save).super_method.super_method => #<Method: ActiveRecord::Validations#save> >> ✅ ✅ ✅
  66. >> Post.new.save >> Post.new.method(:save) => #<Method: ActiveRecord::Suppressor#save> >> Post.new.method(:save).super_method =>

    #<Method: ActiveRecord::Transactions#save> >> Post.new.method(:save).super_method.super_method => #<Method: ActiveRecord::Validations#save> >> Post.new.method(:save).super_method.super_method.super_method ✅ ✅ ✅
  67. >> Post.new.save >> Post.new.method(:save) => #<Method: ActiveRecord::Suppressor#save> >> Post.new.method(:save).super_method =>

    #<Method: ActiveRecord::Transactions#save> >> Post.new.method(:save).super_method.super_method => #<Method: ActiveRecord::Validations#save> >> Post.new.method(:save).super_method.super_method.super_method => #<Method: ActiveRecord::Persistence#save> >> ✅ ✅ ✅ ✅
  68. >> Post.new.save >> Post.new.method(:save) => #<Method: ActiveRecord::Suppressor#save> >> Post.new.method(:save).super_method =>

    #<Method: ActiveRecord::Transactions#save> >> Post.new.method(:save).super_method.super_method => #<Method: ActiveRecord::Validations#save> >> Post.new.method(:save).super_method.super_method.super_method => #<Method: ActiveRecord::Persistence#save> >> Post.new.method(:save).super_method.super_method.super_method.super_method ✅ ✅ ✅ ✅
  69. >> Post.new.save >> Post.new.method(:save) => #<Method: ActiveRecord::Suppressor#save> >> Post.new.method(:save).super_method =>

    #<Method: ActiveRecord::Transactions#save> >> Post.new.method(:save).super_method.super_method => #<Method: ActiveRecord::Validations#save> >> Post.new.method(:save).super_method.super_method.super_method => #<Method: ActiveRecord::Persistence#save> >> Post.new.method(:save).super_method.super_method.super_method.super_method => nil >> ✅ ✅ ✅ ✅
  70. >> "something".method(:empty?).source MethodSource::SourceNotFoundError: Could not locate source for empty?! >>

  71. >> "something".method(:empty?).source MethodSource::SourceNotFoundError: Could not locate source for empty?! >>

    "something".method(:empty?).source_location => nil
  72. try(:length) try!(:length) "something" 9 9 nil nil nil What’s the

    difference between try and try!? >>
  73. try(:length) try!(:length) "something" 9 9 nil nil nil What’s the

    difference between try and try!? >>
  74. try(:length) try!(:length) "something" 9 9 nil nil nil What’s the

    difference between try and try!? >>
  75. What’s the difference between try and try!? >> "something".method(:try).source.display

  76. What’s the difference between try and try!? >> "something".method(:try).source.display def

    try(method_name = nil, *args, &b) if method_name.nil? && block_given? if b.arity == 0 instance_eval(&b) else yield self end elsif respond_to?(method_name) public_send(method_name, *args, &b) end end => nil >>
  77. What’s the difference between try and try!? >> "something".method(:try).source.display def

    try(method_name = nil, *args, &b) if method_name.nil? && block_given? if b.arity == 0 instance_eval(&b) else yield self end elsif respond_to?(method_name) public_send(method_name, *args, &b) end end => nil >>
  78. def try(method_name = nil, *args, &b) if method_name.nil? && block_given?

    if b.arity == 0 instance_eval(&b) else yield self end elsif respond_to?(method_name) public_send(method_name, *args, &b) end end
  79. def try(method_name = nil, *args, &b) if method_name.nil? && block_given?

    if b.arity == 0 instance_eval(&b) else yield self end elsif respond_to?(method_name) public_send(method_name, *args, &b) end end Only read relevant code
  80. def try(method_name = nil, *args, &b) if method_name.nil? && block_given?

    if b.arity == 0 instance_eval(&b) else yield self end elsif respond_to?(method_name) public_send(method_name, *args, &b) end end
  81. def try(method_name = nil, *args, &b) if method_name.nil? && block_given?

    if b.arity == 0 instance_eval(&b) else yield self end elsif respond_to?(method_name) public_send(method_name, *args, &b) end end false
  82. def try(method_name = nil, *args, &b) if method_name.nil? && block_given?

    if b.arity == 0 instance_eval(&b) else yield self end elsif respond_to?(method_name) public_send(method_name, *args, &b) end end
  83. def try(method_name = nil, *args, &b) if method_name.nil? && block_given?

    # ... elsif respond_to?(method_name) public_send(method_name, *args, &b) end end
  84. def try(method_name = nil, *args, &b) if method_name.nil? && block_given?

    # ... elsif respond_to?(method_name) public_send(method_name, *args, &b) end end
  85. What’s the difference between try and try!? >> "something".method(:try).source.display def

    try(method_name = nil, *args, &b) if method_name.nil? && block_given? if b.arity == 0 instance_eval(&b) else yield self end elsif respond_to?(method_name) public_send(method_name, *args, &b) end end => nil >>
  86. What’s the difference between try and try!? >> "something".method(:try).source.display def

    try(method_name = nil, *args, &b) if method_name.nil? && block_given? if b.arity == 0 instance_eval(&b) else yield self end elsif respond_to?(method_name) public_send(method_name, *args, &b) end end => nil >> nil.method(:try).source.display def try(method_name = nil, *args) nil end => nil
  87. What’s the difference between try and try!? >> "something".method(:try).source.display def

    try(method_name = nil, *args, &b) if method_name.nil? && block_given? if b.arity == 0 instance_eval(&b) else yield self end elsif respond_to?(method_name) public_send(method_name, *args, &b) end end => nil >> nil.method(:try).source.display def try(method_name = nil, *args) nil end => nil
  88. def try(method_name = nil, *args) nil end

  89. What’s the difference between try and try!? >>

  90. What’s the difference between try and try!? >> “something".method(:try!).source.display

  91. What’s the difference between try and try!? >> "something".method(:try!).source.display def

    try!(method_name = nil, *args, &b) if method_name.nil? && block_given? if b.arity == 0 instance_eval(&b) else yield self end else public_send(method_name, *args, &b) end end => nil >>
  92. What’s the difference between try and try!? >> "something".method(:try!).source.display def

    try!(method_name = nil, *args, &b) if method_name.nil? && block_given? if b.arity == 0 instance_eval(&b) else yield self end else public_send(method_name, *args, &b) end end => nil >>
  93. def try!(method_name = nil, *args, &b) if method_name.nil? && block_given?

    if b.arity == 0 instance_eval(&b) else yield self end else public_send(method_name, *args, &b) end end
  94. def try!(method_name = nil, *args, &b) if method_name.nil? && block_given?

    if b.arity == 0 instance_eval(&b) else yield self end else public_send(method_name, *args, &b) end end
  95. def try!(method_name = nil, *args, &b) if method_name.nil? && block_given?

    if b.arity == 0 instance_eval(&b) else yield self end else public_send(method_name, *args, &b) end end false
  96. def try!(method_name = nil, *args, &b) if method_name.nil? && block_given?

    if b.arity == 0 instance_eval(&b) else yield self end else public_send(method_name, *args, &b) end end
  97. def try!(method_name = nil, *args, &b) if method_name.nil? && block_given?

    # ... else public_send(method_name, *args, &b) end end
  98. def try!(method_name = nil, *args, &b) if method_name.nil? && block_given?

    # ... else public_send(method_name, *args, &b) end end
  99. def try(method_name = nil, *args, &b) if method_name.nil? && block_given?

    # ... elsif respond_to?(method_name) public_send(method_name, *args, &b) end end def try!(method_name = nil, *args, &b) if method_name.nil? && block_given? # ... else public_send(method_name, *args, &b) end end
  100. def try(method_name = nil, *args, &b) if method_name.nil? && block_given?

    # ... elsif respond_to?(method_name) public_send(method_name, *args, &b) end end def try!(method_name = nil, *args, &b) if method_name.nil? && block_given? # ... else public_send(method_name, *args, &b) end end
  101. What’s the difference between try and try!? >>

  102. What’s the difference between try and try!? >> "something".try(:lengthhhhh) =>

    nil >>
  103. What’s the difference between try and try!? >> "something".try(:lengthhhhh) =>

    nil >> "something".try!(:lengthhhhh) NoMethodError: undefined method `lengthhhhh' for "something":String
  104. What’s the difference between try and try!? >> "something".method(:try!).source.display def

    try!(method_name = nil, *args, &b) if method_name.nil? && block_given? if b.arity == 0 instance_eval(&b) else yield self end else public_send(method_name, *args, &b) end end => nil >>
  105. What’s the difference between try and try!? >> "something".method(:try!).source.display def

    try!(method_name = nil, *args, &b) if method_name.nil? && block_given? if b.arity == 0 instance_eval(&b) else yield self end else public_send(method_name, *args, &b) end end => nil >> nil.method(:try!).source.display def try!(method_name = nil, *args) nil end => nil
  106. What’s the difference between try and try!? >> "something".method(:try!).source.display def

    try!(method_name = nil, *args, &b) if method_name.nil? && block_given? if b.arity == 0 instance_eval(&b) else yield self end else public_send(method_name, *args, &b) end end => nil >> nil.method(:try!).source.display def try!(method_name = nil, *args) nil end => nil
  107. def try!(method_name = nil, *args) nil end

  108. def try(method_name = nil, *args) nil end def try!(method_name =

    nil, *args) nil end
  109. For nil, they’re the same. For everything else, try! is

    more strict. What’s the difference between try and try!? >> "something".try(:lengthhhhh) => nil >> "something".try!(:lengthhhhh) NoMethodError: undefined method `lengthhhhh' for "something":String >> nil.try(:lengthhhh) => nil >> nil.try!(:lengthhhh)
  110. For nil, they’re the same. For everything else, try! is

    more strict. What’s the difference between try and try!? >> "something".try(:lengthhhhh) => nil >> "something".try!(:lengthhhhh) NoMethodError: undefined method `lengthhhhh' for "something":String >> nil.try(:lengthhhh) => nil
  111. 1. Ask a question What’s the difference between try and

    try!? 2. Start with what you know Look at try and try! code 3. Only read relevant code Skim 20 lines, read 6 lines
  112. How you spend your time Obstacles Code Spelunking real work

  113. None
  114. We need a way to keep track of which request

    enqueued a job. Can you figure out a way to add that?
  115. class ApplicationController < ActionController::Base before_action do Current.request_id = request.id end

    end
  116. class ApplicationController < ActionController::Base before_action do Current.request_id = request.id end

    end class ReportsController < ApplicationController def create ReportJob.perform_later # ... end end
  117. class ApplicationJob < ActiveJob::Base attr_accessor :request_id end

  118. class ApplicationJob < ActiveJob::Base attr_accessor :request_id end class ReportJob <

    ApplicationJob queue_as :default def perform(*args) # ... puts "request_id: #{request_id.inspect}" end end
  119. $ rails c Loading development environment (Rails 6.0.0) >>

  120. $ rails c Loading development environment (Rails 6.0.0) >> Current.request_id

    = "abcdef" => "abcdef" >>
  121. $ rails c Loading development environment (Rails 6.0.0) >> Current.request_id

    = "abcdef" => "abcdef" >> ReportJob.perform_later >>
  122. $ rails c Loading development environment (Rails 6.0.0) >> Current.request_id

    = "abcdef" => "abcdef" >> ReportJob.perform_later >> m, `$b .ss, $$: .,d$ `$$P,d$P' .,md$P"' ,$$$$$bmmd$$$P^' .d$$$$$$$$$$P' $$^' `"^$$$' ____ _ _ _ _ $: ,$$: / ___|(_) __| | ___| | _(_) __ _ `b :$$ \___ \| |/ _` |/ _ \ |/ / |/ _` | $$: ___) | | (_| | __/ <| | (_| | $$ |____/|_|\__,_|\___|_|\_\_|\__, | .d$$ |_|
  123. $ rails c Loading development environment (Rails 6.0.0) >> Current.request_id

    = "abcdef" => "abcdef" >> ReportJob.perform_later >> m, `$b .ss, $$: .,d$ `$$P,d$P' .,md$P"' ,$$$$$bmmd$$$P^' .d$$$$$$$$$$P' $$^' `"^$$$' ____ _ _ _ _ $: ,$$: / ___|(_) __| | ___| | _(_) __ _ `b :$$ \___ \| |/ _` |/ _ \ |/ / |/ _` | $$: ___) | | (_| | __/ <| | (_| | $$ |____/|_|\__,_|\___|_|\_\_|\__, | .d$$ |_| ReportJob JID-123 INFO: start request_id: nil ReportJob JID-123 INFO: done
  124. How do we add request_id to every job?

  125. How do we add request_id to every job? $ rails

    c Loading development environment (Rails 6.0.0) >>
  126. How do we add request_id to every job? $ rails

    c Loading development environment (Rails 6.0.0) >> ReportJob.method(:perform_later).source.display
  127. How do we add request_id to every job? $ rails

    c Loading development environment (Rails 6.0.0) >> ReportJob.method(:perform_later).source.display def perform_later(*args) job_or_instantiate(*args).enqueue end => nil >>
  128. How do we add request_id to every job? $ rails

    c Loading development environment (Rails 6.0.0) >> ReportJob.method(:perform_later).source.display def perform_later(*args) job_or_instantiate(*args).enqueue end => nil >>
  129. How do we add request_id to every job? >>

  130. How do we add request_id to every job? >> ReportJob.job_or_instantiate

  131. How do we add request_id to every job? >> ReportJob.job_or_instantiate.method(:enqueue).source.display

  132. How do we add request_id to every job? >> ReportJob.job_or_instantiate.method(:enqueue).source.display

    NoMethodError: private method `job_or_instantiate' called for ReportJob:Class from (pry):5:in `__pry__’ >>
  133. How do we add request_id to every job? >> ReportJob.job_or_instantiate.method(:enqueue).source.display

    NoMethodError: private method `job_or_instantiate' called for ReportJob:Class from (pry):5:in `__pry__’ >> ReportJob.send(:job_or_instantiate)
  134. How do we add request_id to every job? >> ReportJob.job_or_instantiate.method(:enqueue).source.display

    NoMethodError: private method `job_or_instantiate' called for ReportJob:Class from (pry):5:in `__pry__’ >> ReportJob.send(:job_or_instantiate).method(:enqueue).source.display
  135. How do we add request_id to every job? >> ReportJob.job_or_instantiate.method(:enqueue).source.display

    NoMethodError: private method `job_or_instantiate' called for ReportJob:Class from (pry):5:in `__pry__’ >> ReportJob.send(:job_or_instantiate).method(:enqueue).source.display def enqueue(options = {}) self.scheduled_at = options[:wait].seconds.from_now.to_f if options[:wait] self.scheduled_at = options[:wait_until].to_f if options[:wait_until] self.queue_name = self.class.queue_name_from_part(options[:queue]) if options[:queue] self.priority = options[:priority].to_i if options[:priority] successfully_enqueued = false run_callbacks :enqueue do if scheduled_at self.class.queue_adapter.enqueue_at self, scheduled_at else self.class.queue_adapter.enqueue self end successfully_enqueued = true end if successfully_enqueued self else if self.class.return_false_on_aborted_enqueue false else ActiveSupport::Deprecation.warn( "Rails 6.0 will return false when the enqueuing is aborted. Make sure your code doesn't depend on it" \ " returning the instance of the job and set `config.active_job.return_false_on_aborted_enqueue = true`" \ " to remove the deprecations." ) self end end end => nil
  136. How do we add request_id to every job? >> ReportJob.job_or_instantiate.method(:enqueue).source.display

    NoMethodError: private method `job_or_instantiate' called for ReportJob:Class from (pry):5:in `__pry__’ >> ReportJob.send(:job_or_instantiate).method(:enqueue).source.display def enqueue(options = {}) self.scheduled_at = options[:wait].seconds.from_now.to_f if options[:wait] self.scheduled_at = options[:wait_until].to_f if options[:wait_until] self.queue_name = self.class.queue_name_from_part(options[:queue]) if options[:queue] self.priority = options[:priority].to_i if options[:priority] successfully_enqueued = false run_callbacks :enqueue do if scheduled_at self.class.queue_adapter.enqueue_at self, scheduled_at else self.class.queue_adapter.enqueue self end successfully_enqueued = true end if successfully_enqueued self else if self.class.return_false_on_aborted_enqueue false else ActiveSupport::Deprecation.warn( "Rails 6.0 will return false when the enqueuing is aborted. Make sure your code doesn't depend on it" \ " returning the instance of the job and set `config.active_job.return_false_on_aborted_enqueue = true`" \ " to remove the deprecations." ) self end end end => nil
  137. def enqueue(options = {}) self.scheduled_at = options[:wait].seconds.from_now.to_f if options[:wait] self.scheduled_at

    = options[:wait_until].to_f if options[:wait_until] self.queue_name = self.class.queue_name_from_part(options[:queue]) if options[:queue] self.priority = options[:priority].to_i if options[:priority] successfully_enqueued = false run_callbacks :enqueue do if scheduled_at self.class.queue_adapter.enqueue_at self, scheduled_at else self.class.queue_adapter.enqueue self end successfully_enqueued = true end if successfully_enqueued self else if self.class.return_false_on_aborted_enqueue false else ActiveSupport::Deprecation.warn( "Rails 6.0 will return false when the enqueuing is aborted. Make sure your code doesn't depend on it" \ " returning the instance of the job and set `config.active_job.return_false_on_aborted_enqueue = true`" \ " to remove the deprecations." ) self end end end
  138. def enqueue(options = {}) self.scheduled_at = options[:wait].seconds.from_now.to_f if options[:wait] self.scheduled_at

    = options[:wait_until].to_f if options[:wait_until] self.queue_name = self.class.queue_name_from_part(options[:queue]) if options[:queue] self.priority = options[:priority].to_i if options[:priority] successfully_enqueued = false run_callbacks :enqueue do if scheduled_at self.class.queue_adapter.enqueue_at self, scheduled_at else self.class.queue_adapter.enqueue self end successfully_enqueued = true end if successfully_enqueued self else if self.class.return_false_on_aborted_enqueue false else ActiveSupport::Deprecation.warn( "Rails 6.0 will return false when the enqueuing is aborted. Make sure your code doesn't depend on it" \ " returning the instance of the job and set `config.active_job.return_false_on_aborted_enqueue = true`" \ " to remove the deprecations." ) self end end end 1 2 3
  139. def enqueue(options = {}) self.scheduled_at = options[:wait].seconds.from_now.to_f if options[:wait] self.scheduled_at

    = options[:wait_until].to_f if options[:wait_until] self.queue_name = self.class.queue_name_from_part(options[:queue]) if options[:queue] self.priority = options[:priority].to_i if options[:priority] successfully_enqueued = false run_callbacks :enqueue do if scheduled_at self.class.queue_adapter.enqueue_at self, scheduled_at else self.class.queue_adapter.enqueue self end successfully_enqueued = true end if successfully_enqueued self else if self.class.return_false_on_aborted_enqueue false else ActiveSupport::Deprecation.warn( "Rails 6.0 will return false when the enqueuing is aborted. Make sure your code doesn't depend on it" \ " returning the instance of the job and set `config.active_job.return_false_on_aborted_enqueue = true`" \ " to remove the deprecations." ) self end end end 1 2 3
  140. def enqueue(options = {}) self.scheduled_at = options[:wait].seconds.from_now.to_f if options[:wait] self.scheduled_at

    = options[:wait_until].to_f if options[:wait_until] self.queue_name = self.class.queue_name_from_part(options[:queue]) if options[:queue] self.priority = options[:priority].to_i if options[:priority] successfully_enqueued = false run_callbacks :enqueue do if scheduled_at self.class.queue_adapter.enqueue_at self, scheduled_at else self.class.queue_adapter.enqueue self end successfully_enqueued = true end if successfully_enqueued self else if self.class.return_false_on_aborted_enqueue false else ActiveSupport::Deprecation.warn( "Rails 6.0 will return false when the enqueuing is aborted. Make sure your code doesn't depend on it" \ " returning the instance of the job and set `config.active_job.return_false_on_aborted_enqueue = true`" \ " to remove the deprecations." ) self end end end 1 2 3 1 self.scheduled_at = options[:wait].seconds.from_now.to_f if options[:wait] self.scheduled_at = options[:wait_until].to_f if options[:wait_until] self.queue_name = self.class.queue_name_from_part(options[:queue]) if options[:queue] self.priority = options[:priority].to_i if options[:priority] successfully_enqueued = false 1. Variable assignment
  141. def enqueue(options = {}) self.scheduled_at = options[:wait].seconds.from_now.to_f if options[:wait] self.scheduled_at

    = options[:wait_until].to_f if options[:wait_until] self.queue_name = self.class.queue_name_from_part(options[:queue]) if options[:queue] self.priority = options[:priority].to_i if options[:priority] successfully_enqueued = false run_callbacks :enqueue do if scheduled_at self.class.queue_adapter.enqueue_at self, scheduled_at else self.class.queue_adapter.enqueue self end successfully_enqueued = true end if successfully_enqueued self else if self.class.return_false_on_aborted_enqueue false else ActiveSupport::Deprecation.warn( "Rails 6.0 will return false when the enqueuing is aborted. Make sure your code doesn't depend on it" \ " returning the instance of the job and set `config.active_job.return_false_on_aborted_enqueue = true`" \ " to remove the deprecations." ) self end end end 1 2 3 1 self.scheduled_at = options[:wait].seconds.from_now.to_f if options[:wait] self.scheduled_at = options[:wait_until].to_f if options[:wait_until] self.queue_name = self.class.queue_name_from_part(options[:queue]) if options[:queue] self.priority = options[:priority].to_i if options[:priority] successfully_enqueued = false 1. Variable assignment
  142. def enqueue(options = {}) self.scheduled_at = options[:wait].seconds.from_now.to_f if options[:wait] self.scheduled_at

    = options[:wait_until].to_f if options[:wait_until] self.queue_name = self.class.queue_name_from_part(options[:queue]) if options[:queue] self.priority = options[:priority].to_i if options[:priority] successfully_enqueued = false run_callbacks :enqueue do if scheduled_at self.class.queue_adapter.enqueue_at self, scheduled_at else self.class.queue_adapter.enqueue self end successfully_enqueued = true end if successfully_enqueued self else if self.class.return_false_on_aborted_enqueue false else ActiveSupport::Deprecation.warn( "Rails 6.0 will return false when the enqueuing is aborted. Make sure your code doesn't depend on it" \ " returning the instance of the job and set `config.active_job.return_false_on_aborted_enqueue = true`" \ " to remove the deprecations." ) self end end end 1 2 3 1 self.scheduled_at = options[:wait].seconds.from_now.to_f if options[:wait] self.scheduled_at = options[:wait_until].to_f if options[:wait_until] self.queue_name = self.class.queue_name_from_part(options[:queue]) if options[:queue] self.priority = options[:priority].to_i if options[:priority] successfully_enqueued = false 1. Variable assignment
  143. def enqueue(options = {}) self.scheduled_at = options[:wait].seconds.from_now.to_f if options[:wait] self.scheduled_at

    = options[:wait_until].to_f if options[:wait_until] self.queue_name = self.class.queue_name_from_part(options[:queue]) if options[:queue] self.priority = options[:priority].to_i if options[:priority] successfully_enqueued = false run_callbacks :enqueue do if scheduled_at self.class.queue_adapter.enqueue_at self, scheduled_at else self.class.queue_adapter.enqueue self end successfully_enqueued = true end if successfully_enqueued self else if self.class.return_false_on_aborted_enqueue false else ActiveSupport::Deprecation.warn( "Rails 6.0 will return false when the enqueuing is aborted. Make sure your code doesn't depend on it" \ " returning the instance of the job and set `config.active_job.return_false_on_aborted_enqueue = true`" \ " to remove the deprecations." ) self end end end 1 2 3 1 self.scheduled_at = options[:wait].seconds.from_now.to_f if options[:wait] self.scheduled_at = options[:wait_until].to_f if options[:wait_until] self.queue_name = self.class.queue_name_from_part(options[:queue]) if options[:queue] self.priority = options[:priority].to_i if options[:priority] successfully_enqueued = false 1. Variable assignment
  144. def enqueue(options = {}) self.scheduled_at = options[:wait].seconds.from_now.to_f if options[:wait] self.scheduled_at

    = options[:wait_until].to_f if options[:wait_until] self.queue_name = self.class.queue_name_from_part(options[:queue]) if options[:queue] self.priority = options[:priority].to_i if options[:priority] successfully_enqueued = false run_callbacks :enqueue do if scheduled_at self.class.queue_adapter.enqueue_at self, scheduled_at else self.class.queue_adapter.enqueue self end successfully_enqueued = true end if successfully_enqueued self else if self.class.return_false_on_aborted_enqueue false else ActiveSupport::Deprecation.warn( "Rails 6.0 will return false when the enqueuing is aborted. Make sure your code doesn't depend on it" \ " returning the instance of the job and set `config.active_job.return_false_on_aborted_enqueue = true`" \ " to remove the deprecations." ) self end end end 2 3 1
  145. def enqueue(options = {}) # ... run_callbacks :enqueue do if

    scheduled_at self.class.queue_adapter.enqueue_at self, scheduled_at else self.class.queue_adapter.enqueue self end successfully_enqueued = true end if successfully_enqueued self else if self.class.return_false_on_aborted_enqueue false else ActiveSupport::Deprecation.warn( "Rails 6.0 will return false when the enqueuing is aborted. Make sure your code doesn't depend on it" \ " returning the instance of the job and set `config.active_job.return_false_on_aborted_enqueue = true`" \ " to remove the deprecations." ) self end end end 1 2 3
  146. def enqueue(options = {}) # ... run_callbacks :enqueue do if

    scheduled_at self.class.queue_adapter.enqueue_at self, scheduled_at else self.class.queue_adapter.enqueue self end successfully_enqueued = true end if successfully_enqueued self else if self.class.return_false_on_aborted_enqueue false else ActiveSupport::Deprecation.warn( "Rails 6.0 will return false when the enqueuing is aborted. Make sure your code doesn't depend on it" \ " returning the instance of the job and set `config.active_job.return_false_on_aborted_enqueue = true`" \ " to remove the deprecations." ) self end end end 2 3
  147. def enqueue(options = {}) # ... run_callbacks :enqueue do if

    scheduled_at self.class.queue_adapter.enqueue_at self, scheduled_at else self.class.queue_adapter.enqueue self end successfully_enqueued = true end if successfully_enqueued self else if self.class.return_false_on_aborted_enqueue false else ActiveSupport::Deprecation.warn( "Rails 6.0 will return false when the enqueuing is aborted. Make sure your code doesn't depend on it" \ " returning the instance of the job and set `config.active_job.return_false_on_aborted_enqueue = true`" \ " to remove the deprecations." ) self end end end 2 3
  148. def enqueue(options = {}) # ... run_callbacks :enqueue do if

    scheduled_at self.class.queue_adapter.enqueue_at self, scheduled_at else self.class.queue_adapter.enqueue self end successfully_enqueued = true end if successfully_enqueued self else if self.class.return_false_on_aborted_enqueue false else ActiveSupport::Deprecation.warn( "Rails 6.0 will return false when the enqueuing is aborted. Make sure your code doesn't depend on it" \ " returning the instance of the job and set `config.active_job.return_false_on_aborted_enqueue = true`" \ " to remove the deprecations." ) self end end end 2 3 2 2. Method with a block run_callbacks :enqueue do if scheduled_at self.class.queue_adapter.enqueue_at self, scheduled_at else self.class.queue_adapter.enqueue self end successfully_enqueued = true end
  149. def enqueue(options = {}) # ... run_callbacks :enqueue do if

    scheduled_at self.class.queue_adapter.enqueue_at self, scheduled_at else self.class.queue_adapter.enqueue self end successfully_enqueued = true end if successfully_enqueued self else if self.class.return_false_on_aborted_enqueue false else ActiveSupport::Deprecation.warn( "Rails 6.0 will return false when the enqueuing is aborted. Make sure your code doesn't depend on it" \ " returning the instance of the job and set `config.active_job.return_false_on_aborted_enqueue = true`" \ " to remove the deprecations." ) self end end end 3 2
  150. def enqueue(options = {}) # ... run_callbacks :enqueue do if

    scheduled_at self.class.queue_adapter.enqueue_at self, scheduled_at else self.class.queue_adapter.enqueue self end successfully_enqueued = true end if successfully_enqueued self else if self.class.return_false_on_aborted_enqueue false else ActiveSupport::Deprecation.warn( "Rails 6.0 will return false when the enqueuing is aborted. Make sure your code doesn't depend on it" \ " returning the instance of the job and set `config.active_job.return_false_on_aborted_enqueue = true`" \ " to remove the deprecations." ) self end end end 3 2
  151. 3. Conditional if successfully_enqueued self else if self.class.return_false_on_aborted_enqueue false else

    ActiveSupport::Deprecation.warn( "Rails 6.0 will return false when the enqueuing is aborted. Make sure your code " returning the instance of the job and set `config.active_job.return_false_on_ " to remove the deprecations." ) self end end
  152. 3. Conditional if successfully_enqueued self else if self.class.return_false_on_aborted_enqueue false else

    ActiveSupport::Deprecation.warn( "Rails 6.0 will return false when the enqueuing is aborted. Make sure your code " returning the instance of the job and set `config.active_job.return_false_on_ " to remove the deprecations." ) self end end
  153. if successfully_enqueued self else if self.class.return_false_on_aborted_enqueue false else ActiveSupport::Deprecation.warn( "Rails

    6.0 will return false when the enqueuing is aborted. Make sure your code " returning the instance of the job and set `config.active_job.return_false_on_ " to remove the deprecations." ) self end end 3. Conditional
  154. if successfully_enqueued self else if self.class.return_false_on_aborted_enqueue false else ActiveSupport::Deprecation.warn( "Rails

    6.0 will return false when the enqueuing is aborted. Make sure your code " returning the instance of the job and set `config.active_job.return_false_on_ " to remove the deprecations." ) self end end 3. Conditional
  155. def enqueue(options = {}) # ... run_callbacks :enqueue do if

    scheduled_at self.class.queue_adapter.enqueue_at self, scheduled_at else self.class.queue_adapter.enqueue self end successfully_enqueued = true end if successfully_enqueued self else if self.class.return_false_on_aborted_enqueue false else ActiveSupport::Deprecation.warn( "Rails 6.0 will return false when the enqueuing is aborted. Make sure your code doesn't depend on it" \ " returning the instance of the job and set `config.active_job.return_false_on_aborted_enqueue = true`" \ " to remove the deprecations." ) self end end end 2 3
  156. def enqueue(options = {}) # ... run_callbacks :enqueue do if

    scheduled_at self.class.queue_adapter.enqueue_at self, scheduled_at else self.class.queue_adapter.enqueue self end successfully_enqueued = true end # ... end 2 3
  157. def enqueue(options = {}) # ... run_callbacks :enqueue do if

    scheduled_at self.class.queue_adapter.enqueue_at self, scheduled_at else self.class.queue_adapter.enqueue self end successfully_enqueued = true end # ... end 2
  158. def enqueue(options = {}) # ... run_callbacks :enqueue do if

    scheduled_at self.class.queue_adapter.enqueue_at self, scheduled_at else self.class.queue_adapter.enqueue self end successfully_enqueued = true end # ... end 2
  159. def enqueue(options = {}) # ... run_callbacks :enqueue do if

    scheduled_at self.class.queue_adapter.enqueue_at self, scheduled_at else self.class.queue_adapter.enqueue self end successfully_enqueued = true end # ... end 2
  160. def enqueue(options = {}) # ... run_callbacks :enqueue do if

    scheduled_at self.class.queue_adapter.enqueue_at self, scheduled_at else self.class.queue_adapter.enqueue self end successfully_enqueued = true end # ... end 2
  161. def enqueue(options = {}) # ... run_callbacks :enqueue do if

    scheduled_at # ... else self.class.queue_adapter.enqueue self end successfully_enqueued = true end # ... end 2
  162. def enqueue(options = {}) # ... run_callbacks :enqueue do if

    scheduled_at # ... else self.class.queue_adapter.enqueue self end successfully_enqueued = true end # ... end 2
  163. How do we add request_id to every job? >>

  164. How do we add request_id to every job? >> ReportJob.queue_adapter

  165. How do we add request_id to every job? >> ReportJob.queue_adapter.method(:enqueue).source.display

  166. How do we add request_id to every job? >> ReportJob.queue_adapter.method(:enqueue).source.display

    def enqueue(job) #:nodoc: # Sidekiq::Client does not support symbols as keys job.provider_job_id = Sidekiq::Client.push \ "class" => JobWrapper, "wrapped" => job.class.to_s, "queue" => job.queue_name, "args" => [ job.serialize ] end => nil
  167. How do we add request_id to every job? >> ReportJob.queue_adapter.method(:enqueue).source.display

    def enqueue(job) #:nodoc: # Sidekiq::Client does not support symbols as keys job.provider_job_id = Sidekiq::Client.push \ "class" => JobWrapper, "wrapped" => job.class.to_s, "queue" => job.queue_name, "args" => [ job.serialize ] end => nil
  168. How do we add request_id to every job? >> ReportJob.queue_adapter.method(:enqueue).source.display

    def enqueue(job) #:nodoc: # Sidekiq::Client does not support symbols as keys job.provider_job_id = Sidekiq::Client.push \ "class" => JobWrapper, "wrapped" => job.class.to_s, "queue" => job.queue_name, "args" => [ job.serialize ] end => nil
  169. How do we add request_id to every job? >>

  170. How do we add request_id to every job? >> ReportJob.new

  171. How do we add request_id to every job? >> ReportJob.new.method(:serialize).source.display

  172. How do we add request_id to every job? >> ReportJob.new.method(:serialize).source.display

    def serialize { "job_class" => self.class.name, "job_id" => job_id, "provider_job_id" => provider_job_id, "queue_name" => queue_name, "priority" => priority, "arguments" => serialize_arguments_if_needed(arguments), "executions" => executions, "exception_executions" => exception_executions, "locale" => I18n.locale.to_s, "timezone" => Time.zone.try(:name), "enqueued_at" => Time.now.utc.iso8601 } end => nil >>
  173. How do we add request_id to every job? >> ReportJob.new.method(:serialize).source.display

    def serialize { "job_class" => self.class.name, "job_id" => job_id, "provider_job_id" => provider_job_id, "queue_name" => queue_name, "priority" => priority, "arguments" => serialize_arguments_if_needed(arguments), "executions" => executions, "exception_executions" => exception_executions, "locale" => I18n.locale.to_s, "timezone" => Time.zone.try(:name), "enqueued_at" => Time.now.utc.iso8601 } end => nil >>
  174. How do we add request_id to every job? >> ReportJob.new.method(:serialize).source.display

    def serialize { "job_class" => self.class.name, "job_id" => job_id, "provider_job_id" => provider_job_id, "queue_name" => queue_name, "priority" => priority, "arguments" => serialize_arguments_if_needed(arguments), "executions" => executions, "exception_executions" => exception_executions, "locale" => I18n.locale.to_s, "timezone" => Time.zone.try(:name), "enqueued_at" => Time.now.utc.iso8601 } end => nil >>
  175. How do we add request_id to every job? >> ReportJob.new.method(:serialize).source.display

    def serialize { "job_class" => self.class.name, "job_id" => job_id, "provider_job_id" => provider_job_id, "queue_name" => queue_name, "priority" => priority, "arguments" => serialize_arguments_if_needed(arguments), "executions" => executions, "exception_executions" => exception_executions, "locale" => I18n.locale.to_s, "timezone" => Time.zone.try(:name), "enqueued_at" => Time.now.utc.iso8601 } end => nil >> “request_id” => Current.request_id
  176. class ApplicationJob < ActiveJob::Base # ... end

  177. class ApplicationJob < ActiveJob::Base # ... def serialize end end

  178. class ApplicationJob < ActiveJob::Base # ... def serialize super end

    end
  179. class ApplicationJob < ActiveJob::Base # ... def serialize super.merge("request_id" =>

    Current.request_id) end end
  180. How do we add request_id to every job? >>

  181. How do we add request_id to every job? >> Current.request_id

    = "abcdef" => "abcdef" >>
  182. How do we add request_id to every job? >> Current.request_id

    = "abcdef" => "abcdef" >> ReportJob.new
  183. How do we add request_id to every job? >> Current.request_id

    = "abcdef" => "abcdef" >> ReportJob.new.serialize
  184. How do we add request_id to every job? >> Current.request_id

    = "abcdef" => "abcdef" >> ReportJob.new.serialize["request_id"]
  185. How do we add request_id to every job? >> Current.request_id

    = "abcdef" => "abcdef" >> ReportJob.new.serialize["request_id"] => "abcdef" >>
  186. >> How do we add request_id to every job?

  187. >> Current.request_id = "abcdef" => "abcdef" How do we add

    request_id to every job?
  188. >> Current.request_id = "abcdef" => "abcdef" >> ReportJob.perform_later >> How

    do we add request_id to every job?
  189. >> Current.request_id = "abcdef" => "abcdef" >> ReportJob.perform_later >> m,

    `$b .ss, $$: .,d$ `$$P,d$P' .,md$P"' ,$$$$$bmmd$$$P^' .d$$$$$$$$$$P' $$^' `"^$$$' ____ _ _ _ _ $: ,$$: / ___|(_) __| | ___| | _(_) __ _ `b :$$ \___ \| |/ _` |/ _ \ |/ / |/ _` | $$: ___) | | (_| | __/ <| | (_| | $$ |____/|_|\__,_|\___|_|\_\_|\__, | .d$$ |_| How do we add request_id to every job?
  190. >> Current.request_id = "abcdef" => "abcdef" >> ReportJob.perform_later >> m,

    `$b .ss, $$: .,d$ `$$P,d$P' .,md$P"' ,$$$$$bmmd$$$P^' .d$$$$$$$$$$P' $$^' `"^$$$' ____ _ _ _ _ $: ,$$: / ___|(_) __| | ___| | _(_) __ _ `b :$$ \___ \| |/ _` |/ _ \ |/ / |/ _` | $$: ___) | | (_| | __/ <| | (_| | $$ |____/|_|\__,_|\___|_|\_\_|\__, | .d$$ |_| ReportJob JID-123 INFO: start request_id: nil ReportJob JID-123 INFO: done How do we add request_id to every job?
  191. ReportJob.perform_later .job_or_instantiate #enqueue queue_adapter.enqueue job.serialize Sidekiq::Client.push

  192. ActiveJob #enqueue #perform_later #serialize #perform ?

  193. ActiveJob #enqueue #perform_later #serialize #perform ?

  194. >> How do we add request_id to every job?

  195. >> exit $ How do we add request_id to every

    job?
  196. >> exit $ bundle open How do we add request_id

    to every job?
  197. >> exit $ bundle open activejob How do we add

    request_id to every job?
  198. >> exit $ bundle open activejob To open a bundled

    gem, set $EDITOR or $BUNDLER_EDITOR $ How do we add request_id to every job?
  199. >> exit $ bundle open activejob To open a bundled

    gem, set $EDITOR or $BUNDLER_EDITOR $ export EDITOR="subl -w" # Sublime Text, or $ How do we add request_id to every job?
  200. >> exit $ bundle open activejob To open a bundled

    gem, set $EDITOR or $BUNDLER_EDITOR $ export EDITOR="subl -w" # Sublime Text, or $ export EDITOR="code -w" # VS Code, or $ How do we add request_id to every job?
  201. >> exit $ bundle open activejob To open a bundled

    gem, set $EDITOR or $BUNDLER_EDITOR $ export EDITOR="subl -w" # Sublime Text, or $ export EDITOR="code -w" # VS Code, or $ export EDITOR="vim" # vim, or whatever you use $ How do we add request_id to every job?
  202. >> exit $ bundle open activejob To open a bundled

    gem, set $EDITOR or $BUNDLER_EDITOR $ export EDITOR="subl -w" # Sublime Text, or $ export EDITOR="code -w" # VS Code, or $ export EDITOR="vim" # vim, or whatever you use $ bundle open activejob How do we add request_id to every job?
  203. >> exit $ bundle open activejob To open a bundled

    gem, set $EDITOR or $BUNDLER_EDITOR $ export EDITOR="subl -w" # Sublime Text, or $ export EDITOR="code -w" # VS Code, or $ export EDITOR="vim" # vim, or whatever you use $ bundle open activejob How do we add request_id to every job?
  204. >> exit $ bundle open activejob To open a bundled

    gem, set $EDITOR or $BUNDLER_EDITOR $ export EDITOR="subl -w" # Sublime Text, or $ export EDITOR="code -w" # VS Code, or $ export EDITOR="vim" # vim, or whatever you use $ bundle open activejob How do we add request_id to every job?
  205. module ActiveJob module QueueAdapters class SidekiqAdapter def enqueue(job) #:nodoc: #

    Sidekiq::Client does not support symbols as keys job.provider_job_id = Sidekiq::Client.push \ "class" => JobWrapper, "wrapped" => job.class.to_s, "queue" => job.queue_name, "args" => [ job.serialize ] end def enqueue_at(job, timestamp) #:nodoc: job.provider_job_id = Sidekiq::Client.push \ "class" => JobWrapper, "wrapped" => job.class.to_s, "queue" => job.queue_name, "args" => [ job.serialize ], "at" => timestamp end class JobWrapper #:nodoc: include Sidekiq::Worker def perform(job_data) Base.execute job_data.merge("provider_job_id" => jid) end end end end end
  206. module ActiveJob module QueueAdapters class SidekiqAdapter def enqueue(job) #:nodoc: #

    Sidekiq::Client does not support symbols as keys job.provider_job_id = Sidekiq::Client.push \ "class" => JobWrapper, "wrapped" => job.class.to_s, "queue" => job.queue_name, "args" => [ job.serialize ] end def enqueue_at(job, timestamp) #:nodoc: job.provider_job_id = Sidekiq::Client.push \ "class" => JobWrapper, "wrapped" => job.class.to_s, "queue" => job.queue_name, "args" => [ job.serialize ], "at" => timestamp end class JobWrapper #:nodoc: include Sidekiq::Worker def perform(job_data) Base.execute job_data.merge("provider_job_id" => jid) end end end end end 1 2 3
  207. module ActiveJob module QueueAdapters class SidekiqAdapter def enqueue(job) #:nodoc: #

    Sidekiq::Client does not support symbols as keys job.provider_job_id = Sidekiq::Client.push \ "class" => JobWrapper, "wrapped" => job.class.to_s, "queue" => job.queue_name, "args" => [ job.serialize ] end def enqueue_at(job, timestamp) #:nodoc: job.provider_job_id = Sidekiq::Client.push \ "class" => JobWrapper, "wrapped" => job.class.to_s, "queue" => job.queue_name, "args" => [ job.serialize ], "at" => timestamp end class JobWrapper #:nodoc: include Sidekiq::Worker def perform(job_data) Base.execute job_data.merge("provider_job_id" => jid) end end end end end 1 2 3
  208. module ActiveJob module QueueAdapters class SidekiqAdapter def enqueue(job) #:nodoc: #

    Sidekiq::Client does not support symbols as keys job.provider_job_id = Sidekiq::Client.push \ "class" => JobWrapper, "wrapped" => job.class.to_s, "queue" => job.queue_name, "args" => [ job.serialize ] end def enqueue_at(job, timestamp) #:nodoc: job.provider_job_id = Sidekiq::Client.push \ "class" => JobWrapper, "wrapped" => job.class.to_s, "queue" => job.queue_name, "args" => [ job.serialize ], "at" => timestamp end class JobWrapper #:nodoc: include Sidekiq::Worker def perform(job_data) Base.execute job_data.merge("provider_job_id" => jid) end end end end end 1 2 3 def enqueue(job) #:nodoc: # Sidekiq::Client does not support symbols as keys job.provider_job_id = Sidekiq::Client.push \ "class" => JobWrapper, "wrapped" => job.class.to_s, "queue" => job.queue_name, "args" => [ job.serialize ] end 1. enqueue method
  209. module ActiveJob module QueueAdapters class SidekiqAdapter def enqueue(job) #:nodoc: #

    Sidekiq::Client does not support symbols as keys job.provider_job_id = Sidekiq::Client.push \ "class" => JobWrapper, "wrapped" => job.class.to_s, "queue" => job.queue_name, "args" => [ job.serialize ] end def enqueue_at(job, timestamp) #:nodoc: job.provider_job_id = Sidekiq::Client.push \ "class" => JobWrapper, "wrapped" => job.class.to_s, "queue" => job.queue_name, "args" => [ job.serialize ], "at" => timestamp end class JobWrapper #:nodoc: include Sidekiq::Worker def perform(job_data) Base.execute job_data.merge("provider_job_id" => jid) end end end end end 1 2 3
  210. module ActiveJob module QueueAdapters class SidekiqAdapter # ... def enqueue_at(job,

    timestamp) #:nodoc: job.provider_job_id = Sidekiq::Client.push \ "class" => JobWrapper, "wrapped" => job.class.to_s, "queue" => job.queue_name, "args" => [ job.serialize ], "at" => timestamp end class JobWrapper #:nodoc: include Sidekiq::Worker def perform(job_data) Base.execute job_data.merge("provider_job_id" => jid) end end end end end 1 2 3
  211. module ActiveJob module QueueAdapters class SidekiqAdapter # ... def enqueue_at(job,

    timestamp) #:nodoc: job.provider_job_id = Sidekiq::Client.push \ "class" => JobWrapper, "wrapped" => job.class.to_s, "queue" => job.queue_name, "args" => [ job.serialize ], "at" => timestamp end class JobWrapper #:nodoc: include Sidekiq::Worker def perform(job_data) Base.execute job_data.merge("provider_job_id" => jid) end end end end end 2 3
  212. module ActiveJob module QueueAdapters class SidekiqAdapter # ... def enqueue_at(job,

    timestamp) #:nodoc: job.provider_job_id = Sidekiq::Client.push \ "class" => JobWrapper, "wrapped" => job.class.to_s, "queue" => job.queue_name, "args" => [ job.serialize ], "at" => timestamp end class JobWrapper #:nodoc: include Sidekiq::Worker def perform(job_data) Base.execute job_data.merge("provider_job_id" => jid) end end end end end 2 3
  213. module ActiveJob module QueueAdapters class SidekiqAdapter def enqueue(job) #:nodoc: #

    Sidekiq::Client does not support symbols as keys job.provider_job_id = Sidekiq::Client.push \ "class" => JobWrapper, "wrapped" => job.class.to_s, "queue" => job.queue_name, "args" => [ job.serialize ] end def enqueue_at(job, timestamp) #:nodoc: job.provider_job_id = Sidekiq::Client.push \ "class" => JobWrapper, "wrapped" => job.class.to_s, "queue" => job.queue_name, "args" => [ job.serialize ], "at" => timestamp end class JobWrapper #:nodoc: include Sidekiq::Worker def perform(job_data) Base.execute job_data.merge("provider_job_id" => jid) end end end end end 1 2 3 def enqueue_at(job, timestamp) #:nodoc: job.provider_job_id = Sidekiq::Client.push \ "class" => JobWrapper, "wrapped" => job.class.to_s, "queue" => job.queue_name, "args" => [ job.serialize ], "at" => timestamp end 2. enqueue_at method
  214. module ActiveJob module QueueAdapters class SidekiqAdapter # ... def enqueue_at(job,

    timestamp) #:nodoc: job.provider_job_id = Sidekiq::Client.push \ "class" => JobWrapper, "wrapped" => job.class.to_s, "queue" => job.queue_name, "args" => [ job.serialize ], "at" => timestamp end class JobWrapper #:nodoc: include Sidekiq::Worker def perform(job_data) Base.execute job_data.merge("provider_job_id" => jid) end end end end end 2 3
  215. module ActiveJob module QueueAdapters class SidekiqAdapter # ... # ...

    class JobWrapper #:nodoc: include Sidekiq::Worker def perform(job_data) Base.execute job_data.merge("provider_job_id" => jid) end end end end end 2 3
  216. module ActiveJob module QueueAdapters class SidekiqAdapter # ... class JobWrapper

    #:nodoc: include Sidekiq::Worker def perform(job_data) Base.execute job_data.merge("provider_job_id" => jid) end end end end end 3
  217. module ActiveJob module QueueAdapters class SidekiqAdapter # ... class JobWrapper

    #:nodoc: include Sidekiq::Worker def perform(job_data) Base.execute job_data.merge("provider_job_id" => jid) end end end end end 3
  218. module ActiveJob module QueueAdapters class SidekiqAdapter # ... class JobWrapper

    #:nodoc: include Sidekiq::Worker def perform(job_data) Base.execute job_data.merge("provider_job_id" => jid) end end end end end 3
  219. module ActiveJob module QueueAdapters class SidekiqAdapter # ... class JobWrapper

    #:nodoc: include Sidekiq::Worker def perform(job_data) Base.execute job_data.merge("provider_job_id" => jid) end end end end end 3
  220. module ActiveJob module QueueAdapters class SidekiqAdapter # ... class JobWrapper

    #:nodoc: include Sidekiq::Worker def perform(job_data) Base.execute job_data.merge("provider_job_id" => jid) end end end end end 3
  221. module ActiveJob module QueueAdapters class SidekiqAdapter # ... class JobWrapper

    #:nodoc: include Sidekiq::Worker def perform(job_data) Base.execute job_data.merge("provider_job_id" => jid) end end end end end 3
  222. module ActiveJob module QueueAdapters class SidekiqAdapter # ... class JobWrapper

    #:nodoc: include Sidekiq::Worker def perform(job_data) byebug Base.execute job_data.merge("provider_job_id" => jid) end end end end end 3
  223. $ rails c Loading development environment (Rails 6.0.0) >> How

    do we add request_id to every job?
  224. $ rails c Loading development environment (Rails 6.0.0) >> Current.request_id

    = "abcdef" => "abcdef" >> How do we add request_id to every job?
  225. $ rails c Loading development environment (Rails 6.0.0) >> Current.request_id

    = "abcdef" => "abcdef" >> ReportJob.perform_later >> How do we add request_id to every job?
  226. $ rails c Loading development environment (Rails 6.0.0) >> Current.request_id

    = "abcdef" => "abcdef" >> ReportJob.perform_later >> How do we add request_id to every job? m, `$b .ss, $$: .,d$ `$$P,d$P' .,md$P"' ,$$$$$bmmd$$$P^' .d$$$$$$$$$$P' $$^' `"^$$$' ____ _ _ _ _ $: ,$$: / ___|(_) __| | ___| | _(_) __ _ `b :$$ \___ \| |/ _` |/ _ \ |/ / |/ _` | $$: ___) | | (_| | __/ <| | (_| | $$ |____/|_|\__,_|\___|_|\_\_|\__, | .d$$ |_| ReportJob JID-123 INFO: start
  227. $ rails c Loading development environment (Rails 6.0.0) >> Current.request_id

    = "abcdef" => "abcdef" >> ReportJob.perform_later >> How do we add request_id to every job? m, `$b .ss, $$: .,d$ `$$P,d$P' .,md$P"' ,$$$$$bmmd$$$P^' .d$$$$$$$$$$P' $$^' `"^$$$' ____ _ _ _ _ $: ,$$: / ___|(_) __| | ___| | _(_) __ _ `b :$$ \___ \| |/ _` |/ _ \ |/ / |/ _` | $$: ___) | | (_| | __/ <| | (_| | $$ |____/|_|\__,_|\___|_|\_\_|\__, | .d$$ |_| ReportJob JID-123 INFO: start
 [26, 35] in activejob-6.0.0.beta3/lib/active_job/queue_adapters/sidekiq_adapter.rb 26: class JobWrapper #:nodoc: 27: include Sidekiq::Worker 28: 29: def perform(job_data) 30: byebug => 31: Base.execute job_data.merge("provider_job_id" => jid) 32: end 33: end 34: end 35: end (byebug)
  228. $ rails c Loading development environment (Rails 6.0.0) >> Current.request_id

    = "abcdef" => "abcdef" >> ReportJob.perform_later >> How do we add request_id to every job? [26, 35] in activejob-6.0.0.beta3/lib/active_job/queue_adapters/sidekiq_adapter.rb 26: class JobWrapper #:nodoc: 27: include Sidekiq::Worker 28: 29: def perform(job_data) 30: byebug => 31: Base.execute job_data.merge("provider_job_id" => jid) 32: end 33: end 34: end 35: end (byebug)
  229. $ rails c Loading development environment (Rails 6.0.0) >> Current.request_id

    = "abcdef" => "abcdef" >> ReportJob.perform_later >> How do we add request_id to every job? [26, 35] in activejob-6.0.0.beta3/lib/active_job/queue_adapters/sidekiq_adapter.rb 26: class JobWrapper #:nodoc: 27: include Sidekiq::Worker 28: 29: def perform(job_data) 30: byebug => 31: Base.execute job_data.merge("provider_job_id" => jid) 32: end 33: end 34: end 35: end (byebug) job_data
  230. $ rails c Loading development environment (Rails 6.0.0) >> Current.request_id

    = "abcdef" => "abcdef" >> ReportJob.perform_later >> How do we add request_id to every job? [26, 35] in activejob-6.0.0.beta3/lib/active_job/queue_adapters/sidekiq_adapter.rb 26: class JobWrapper #:nodoc: 27: include Sidekiq::Worker 28: 29: def perform(job_data) 30: byebug => 31: Base.execute job_data.merge("provider_job_id" => jid) 32: end 33: end 34: end 35: end (byebug) job_data { "job_class"=>"ReportJob", "job_id"=>"d13993c6-dd0f-4323-a1c3-544f2ed3b44a", "provider_job_id"=>nil, "queue_name"=>"default", "priority"=>nil,
  231. $ rails c Loading development environment (Rails 6.0.0) >> Current.request_id

    = "abcdef" => "abcdef" >> ReportJob.perform_later >> How do we add request_id to every job? (byebug) job_data { "job_class"=>"ReportJob", "job_id"=>"d13993c6-dd0f-4323-a1c3-544f2ed3b44a", "provider_job_id"=>nil, "queue_name"=>"default", "priority"=>nil, "arguments"=>[], "executions"=>0, "exception_executions"=>{}, "locale"=>"en", "timezone"=>"UTC", "enqueued_at"=>"2019-04-26T01:11:19Z", "request_id"=>"abcdef" } (byebug)
  232. $ rails c Loading development environment (Rails 6.0.0) >> Current.request_id

    = "abcdef" => "abcdef" >> ReportJob.perform_later >> How do we add request_id to every job? (byebug) job_data { "job_class"=>"ReportJob", "job_id"=>"d13993c6-dd0f-4323-a1c3-544f2ed3b44a", "provider_job_id"=>nil, "queue_name"=>"default", "priority"=>nil, "arguments"=>[], "executions"=>0, "exception_executions"=>{}, "locale"=>"en", "timezone"=>"UTC", "enqueued_at"=>"2019-04-26T01:11:19Z", "request_id"=>"abcdef" } (byebug) job_data["request_id"] "abcdef" (byebug)
  233. $ rails c Loading development environment (Rails 6.0.0) >> Current.request_id

    = "abcdef" => "abcdef" >> ReportJob.perform_later >> How do we add request_id to every job? (byebug)
  234. $ rails c Loading development environment (Rails 6.0.0) >> Current.request_id

    = "abcdef" => "abcdef" >> ReportJob.perform_later >> How do we add request_id to every job? (byebug) Base.method(:execute).source.display
  235. $ rails c Loading development environment (Rails 6.0.0) >> Current.request_id

    = "abcdef" => "abcdef" >> ReportJob.perform_later >> How do we add request_id to every job? (byebug) Base.method(:execute).source.display def execute(job_data) #:nodoc: ActiveJob::Callbacks.run_callbacks(:execute) do job = deserialize(job_data) job.perform_now end end nil (byebug)
  236. $ rails c Loading development environment (Rails 6.0.0) >> Current.request_id

    = "abcdef" => "abcdef" >> ReportJob.perform_later >> How do we add request_id to every job? (byebug) Base.method(:execute).source.display def execute(job_data) #:nodoc: ActiveJob::Callbacks.run_callbacks(:execute) do job = deserialize(job_data) job.perform_now end end nil (byebug)
  237. $ rails c Loading development environment (Rails 6.0.0) >> Current.request_id

    = "abcdef" => "abcdef" >> ReportJob.perform_later >> How do we add request_id to every job? (byebug) Base.method(:execute).source.display def execute(job_data) #:nodoc: ActiveJob::Callbacks.run_callbacks(:execute) do job = deserialize(job_data) job.perform_now end end nil (byebug) Base.method(:deserialize).source.display
  238. $ rails c Loading development environment (Rails 6.0.0) >> Current.request_id

    = "abcdef" => "abcdef" >> ReportJob.perform_later >> How do we add request_id to every job? (byebug) Base.method(:execute).source.display def execute(job_data) #:nodoc: ActiveJob::Callbacks.run_callbacks(:execute) do job = deserialize(job_data) job.perform_now end end nil (byebug) Base.method(:deserialize).source.display def deserialize(job_data) job = job_data["job_class"].constantize.new job.deserialize(job_data) job end nil (byebug)
  239. $ rails c Loading development environment (Rails 6.0.0) >> Current.request_id

    = "abcdef" => "abcdef" >> ReportJob.perform_later >> How do we add request_id to every job? (byebug) Base.method(:execute).source.display def execute(job_data) #:nodoc: ActiveJob::Callbacks.run_callbacks(:execute) do job = deserialize(job_data) job.perform_now end end nil (byebug) Base.method(:deserialize).source.display def deserialize(job_data) job = job_data["job_class"].constantize.new job.deserialize(job_data) job end nil (byebug)
  240. $ rails c Loading development environment (Rails 6.0.0) >> Current.request_id

    = "abcdef" => "abcdef" >> ReportJob.perform_later >> How do we add request_id to every job? (byebug) Base.method(:execute).source.display def execute(job_data) #:nodoc: ActiveJob::Callbacks.run_callbacks(:execute) do job = deserialize(job_data) job.perform_now end end nil (byebug) Base.method(:deserialize).source.display def deserialize(job_data) job = job_data["job_class"].constantize.new job.deserialize(job_data) job end nil (byebug)
  241. $ rails c Loading development environment (Rails 6.0.0) >> Current.request_id

    = "abcdef" => "abcdef" >> ReportJob.perform_later >> How do we add request_id to every job? (byebug) Base.method(:execute).source.display def execute(job_data) #:nodoc: ActiveJob::Callbacks.run_callbacks(:execute) do job = deserialize(job_data) job.perform_now end end nil (byebug) Base.method(:deserialize).source.display def deserialize(job_data) job = job_data["job_class"].constantize.new job.deserialize(job_data) job end nil (byebug)
  242. $ rails c Loading development environment (Rails 6.0.0) >> Current.request_id

    = "abcdef" => "abcdef" >> ReportJob.perform_later >> How do we add request_id to every job? (byebug) Base.method(:execute).source.display def execute(job_data) #:nodoc: ActiveJob::Callbacks.run_callbacks(:execute) do job = deserialize(job_data) job.perform_now end end nil (byebug) Base.method(:deserialize).source.display def deserialize(job_data) job = job_data["job_class"].constantize.new job.deserialize(job_data) job end nil (byebug) job_data["job_class"].constantize.new
  243. $ rails c Loading development environment (Rails 6.0.0) >> Current.request_id

    = "abcdef" => "abcdef" >> ReportJob.perform_later >> How do we add request_id to every job? (byebug) Base.method(:execute).source.display def execute(job_data) #:nodoc: ActiveJob::Callbacks.run_callbacks(:execute) do job = deserialize(job_data) job.perform_now end end nil (byebug) Base.method(:deserialize).source.display def deserialize(job_data) job = job_data["job_class"].constantize.new job.deserialize(job_data) job end nil (byebug) job_data["job_class"].constantize.new.method(:deserialize).source.display
  244. $ rails c Loading development environment (Rails 6.0.0) >> Current.request_id

    = "abcdef" => "abcdef" >> ReportJob.perform_later >> How do we add request_id to every job? (byebug) Base.method(:execute).source.display def execute(job_data) #:nodoc: ActiveJob::Callbacks.run_callbacks(:execute) do job = deserialize(job_data) job.perform_now end end nil (byebug) Base.method(:deserialize).source.display def deserialize(job_data) job = job_data["job_class"].constantize.new job.deserialize(job_data) job end nil (byebug) job_data["job_class"].constantize.new.method(:deserialize).source.display def deserialize(job_data) self.job_id = job_data["job_id"]
  245. $ rails c Loading development environment (Rails 6.0.0) >> Current.request_id

    = "abcdef" => "abcdef" >> ReportJob.perform_later >> How do we add request_id to every job? (byebug) Base.method(:deserialize).source.display def deserialize(job_data) job = job_data["job_class"].constantize.new job.deserialize(job_data) job end nil (byebug) job_data["job_class"].constantize.new.method(:deserialize).source.display def deserialize(job_data) self.job_id = job_data["job_id"] self.provider_job_id = job_data["provider_job_id"] self.queue_name = job_data["queue_name"] self.priority = job_data["priority"] self.serialized_arguments = job_data["arguments"] self.executions = job_data["executions"] self.exception_executions = job_data["exception_executions"] self.locale = job_data["locale"] || I18n.locale.to_s self.timezone = job_data["timezone"] || Time.zone.try(:name)
  246. $ rails c Loading development environment (Rails 6.0.0) >> Current.request_id

    = "abcdef" => "abcdef" >> ReportJob.perform_later >> How do we add request_id to every job? (byebug) job_data["job_class"].constantize.new.method(:deserialize).source.display def deserialize(job_data) self.job_id = job_data["job_id"] self.provider_job_id = job_data["provider_job_id"] self.queue_name = job_data["queue_name"] self.priority = job_data["priority"] self.serialized_arguments = job_data["arguments"] self.executions = job_data["executions"] self.exception_executions = job_data["exception_executions"] self.locale = job_data["locale"] || I18n.locale.to_s self.timezone = job_data["timezone"] || Time.zone.try(:name) self.enqueued_at = job_data["enqueued_at"] end nil (byebug)
  247. $ rails c Loading development environment (Rails 6.0.0) >> Current.request_id

    = "abcdef" => "abcdef" >> ReportJob.perform_later >> How do we add request_id to every job? (byebug) job_data["job_class"].constantize.new.method(:deserialize).source.display def deserialize(job_data) self.job_id = job_data["job_id"] self.provider_job_id = job_data["provider_job_id"] self.queue_name = job_data["queue_name"] self.priority = job_data["priority"] self.serialized_arguments = job_data["arguments"] self.executions = job_data["executions"] self.exception_executions = job_data["exception_executions"] self.locale = job_data["locale"] || I18n.locale.to_s self.timezone = job_data["timezone"] || Time.zone.try(:name) self.enqueued_at = job_data["enqueued_at"] end nil (byebug)
  248. $ rails c Loading development environment (Rails 6.0.0) >> Current.request_id

    = "abcdef" => "abcdef" >> ReportJob.perform_later >> How do we add request_id to every job? (byebug) job_data["job_class"].constantize.new.method(:deserialize).source.display def deserialize(job_data) self.job_id = job_data["job_id"] self.provider_job_id = job_data["provider_job_id"] self.queue_name = job_data["queue_name"] self.priority = job_data["priority"] self.serialized_arguments = job_data["arguments"] self.executions = job_data["executions"] self.exception_executions = job_data["exception_executions"] self.locale = job_data["locale"] || I18n.locale.to_s self.timezone = job_data["timezone"] || Time.zone.try(:name) self.enqueued_at = job_data["enqueued_at"] end nil (byebug)
  249. $ rails c Loading development environment (Rails 6.0.0) >> Current.request_id

    = "abcdef" => "abcdef" >> ReportJob.perform_later >> How do we add request_id to every job? (byebug) job_data["job_class"].constantize.new.method(:deserialize).source.display def deserialize(job_data) self.job_id = job_data["job_id"] self.provider_job_id = job_data["provider_job_id"] self.queue_name = job_data["queue_name"] self.priority = job_data["priority"] self.serialized_arguments = job_data["arguments"] self.executions = job_data["executions"] self.exception_executions = job_data["exception_executions"] self.locale = job_data["locale"] || I18n.locale.to_s self.timezone = job_data["timezone"] || Time.zone.try(:name) self.enqueued_at = job_data["enqueued_at"] end nil (byebug)
  250. $ rails c Loading development environment (Rails 6.0.0) >> Current.request_id

    = "abcdef" => "abcdef" >> ReportJob.perform_later >> How do we add request_id to every job? (byebug) job_data["job_class"].constantize.new.method(:deserialize).source.display def deserialize(job_data) self.job_id = job_data["job_id"] self.provider_job_id = job_data["provider_job_id"] self.queue_name = job_data["queue_name"] self.priority = job_data["priority"] self.serialized_arguments = job_data["arguments"] self.executions = job_data["executions"] self.exception_executions = job_data["exception_executions"] self.locale = job_data["locale"] || I18n.locale.to_s self.timezone = job_data["timezone"] || Time.zone.try(:name) self.enqueued_at = job_data["enqueued_at"] end nil (byebug) self.request_id = job_data["request_id"]
  251. class ApplicationJob < ActiveJob::Base # ... def serialize super.merge("request_id" =>

    Current.request_id) end end
  252. class ApplicationJob < ActiveJob::Base # ... def serialize super.merge("request_id" =>

    Current.request_id) end def deserialize(job_data) end end
  253. class ApplicationJob < ActiveJob::Base # ... def serialize super.merge("request_id" =>

    Current.request_id) end def deserialize(job_data) super end end
  254. class ApplicationJob < ActiveJob::Base # ... def serialize super.merge("request_id" =>

    Current.request_id) end def deserialize(job_data) super self.request_id = job_data["request_id"] end end
  255. >> How do we add request_id to every job?

  256. >> Current.request_id = "abcdef" => "abcdef" How do we add

    request_id to every job?
  257. >> Current.request_id = "abcdef" => "abcdef" >> ReportJob.perform_later >> How

    do we add request_id to every job?
  258. >> Current.request_id = "abcdef" => "abcdef" >> ReportJob.perform_later >> m,

    `$b .ss, $$: .,d$ `$$P,d$P' .,md$P"' ,$$$$$bmmd$$$P^' .d$$$$$$$$$$P' $$^' `"^$$$' ____ _ _ _ _ $: ,$$: / ___|(_) __| | ___| | _(_) __ _ `b :$$ \___ \| |/ _` |/ _ \ |/ / |/ _` | $$: ___) | | (_| | __/ <| | (_| | $$ |____/|_|\__,_|\___|_|\_\_|\__, | .d$$ |_| How do we add request_id to every job?
  259. By adding it to serialization and deserialization. We add request_id

    during serialization and set it during deserialization. >> Current.request_id = "abcdef" => "abcdef" >> ReportJob.perform_later >> m, `$b .ss, $$: .,d$ `$$P,d$P' .,md$P"' ,$$$$$bmmd$$$P^' .d$$$$$$$$$$P' $$^' `"^$$$' ____ _ _ _ _ $: ,$$: / ___|(_) __| | ___| | _(_) __ _ `b :$$ \___ \| |/ _` |/ _ \ |/ / |/ _` | $$: ___) | | (_| | __/ <| | (_| | $$ |____/|_|\__,_|\___|_|\_\_|\__, | .d$$ |_| ReportJob JID-123 INFO: start request_id: "abcdef" ReportJob JID-123 INFO: done How do we add request_id to every job?
  260. By adding it to serialization and deserialization. >> Current.request_id =

    "abcdef" => "abcdef" >> ReportJob.perform_later >> m, `$b .ss, $$: .,d$ `$$P,d$P' .,md$P"' ,$$$$$bmmd$$$P^' .d$$$$$$$$$$P' $$^' `"^$$$' ____ _ _ _ _ $: ,$$: / ___|(_) __| | ___| | _(_) __ _ `b :$$ \___ \| |/ _` |/ _ \ |/ / |/ _` | $$: ___) | | (_| | __/ <| | (_| | $$ |____/|_|\__,_|\___|_|\_\_|\__, | .d$$ |_| ReportJob JID-123 INFO: start request_id: "abcdef" ReportJob JID-123 INFO: done How do we add request_id to every job?
  261. 1. Ask a question How do we add request_id to

    every job? 2. Start with what you know Look at perform_later. 3. Only read relevant code Skim 100 lines, read ~50 lines
  262. 1. Ask a question How do we add request_id to

    every job? 2. Start with what you know Look at perform_later. 3. Only read relevant code Skim 100 lines, read ~50 lines
  263. 1. Ask a question How do we add request_id to

    every job? 2. Start with what you know Look at perform_later. 3. Only read relevant code Skim 100 lines, read ~50 lines
  264. None
  265. https://github.com/deivid-rodriguez/byebug byebug

  266. https://pryrepl.org/

  267. https://pryrepl.org/ >> show-source "hello".empty? From: string.c (C Method): Owner: String

    Visibility: public Number of lines: 7 static VALUE rb_str_empty(VALUE str) { if (RSTRING_LEN(str) == 0) return Qtrue; return Qfalse; }
  268. Average Percentage of Time Spent by Developers 0% 25% 50%

    75% 100% Comprehension
 & Navigation Editing Other 82% 5% 13%
  269. Average Percentage of Time Spent by Developers 0% 25% 50%

    75% 100% Comprehension
 & Navigation Editing Other 82% 5% 13%
  270. Average Percentage of Time Spent by Developers 0% 25% 50%

    75% 100% Comprehension
 & Navigation Editing Other 77% 10% 13%
  271. Thanks. Jordan Raine @jnraine

  272. • Donald Giannatti, Unsplash, https://unsplash.com/photos/OVLa83nRaLQ • Niklas Hamann, Unsplash, https://unsplash.com/photos/Pe4gh8a8mBY

    • By The original uploader was Minghong at English Wikipedia. - Transferred from en.wikipedia to Commons by IngerAlHaosului using CommonsHelper., CC BY-SA 3.0, https://commons.wikimedia.org/ w/index.php?curid=8922606 • Andrew Buchanan, Unsplash, https://unsplash.com/photos/Csf7vDp-Whc • Majid Rangraz, Unsplash, https://unsplash.com/photos/IPMaxeoHXi4 • Rachel, Unsplash, https://unsplash.com/photos/GGlz-QSvL38 • Rohan Makhecha, Unsplash, https://unsplash.com/photos/5fldl8eWIt0 • Eva Darron, Unsplash, https://unsplash.com/photos/oCdVtGFeDC0 • Mike Benna, Unsplash, https://unsplash.com/photos/5Cv3surFZM8 • Luc Tribolet, Unsplash, https://unsplash.com/photos/FQRxB1SimfI • Damian Zaleski, Unsplash, https://unsplash.com/photos/RYyr-k3Ysqg • Jennifer Regnier, Unsplash, https://unsplash.com/photos/sjP0USlCt10 Photo Credits