Artwork

Content provided by Christoph Neumann and Nate Jones, Christoph Neumann, and Nate Jones. All podcast content including episodes, graphics, and podcast descriptions are uploaded and provided directly by Christoph Neumann and Nate Jones, Christoph Neumann, and Nate Jones or their podcast platform partner. If you believe someone is using your copyrighted work without your permission, you can follow the process outlined here https://player.fm/legal.
Player FM - Podcast App
Go offline with the Player FM app!

Episode 009: Channeling Re-Search

26:47
 
Share
 

Manage episode 224136429 series 2463849
Content provided by Christoph Neumann and Nate Jones, Christoph Neumann, and Nate Jones. All podcast content including episodes, graphics, and podcast descriptions are uploaded and provided directly by Christoph Neumann and Nate Jones, Christoph Neumann, and Nate Jones or their podcast platform partner. If you believe someone is using your copyrighted work without your permission, you can follow the process outlined here https://player.fm/legal.

Nate can't decide what to watch on Twitter, and the app restarts are killing him.

  • The Twitterthon continues. "It's an infinite stream of Twitter."
  • Nate wants to watch #clojurescript too.
  • Just change the search string to "#clojure OR #clojurescript"?
  • Should avoid hardcoding the value so we don't have to recompile every time.
  • Command line argument still requires a restart.
  • Let's use a curl UI (like Ep 004)!
  • Wait, what?! Why curl?
    • Can send something into the running process
    • Can separate out the client
    • Builds on top of HTTP, so there are lots of tools for testing (like curl itself)
  • Use a URL query string: http://localhost:8000/search?The+search+string
  • "It's a true query string in the truest sense of the term 'query.'"
  • "It is actually using the thing for the thing it was meant to be."
  • How do we get the query string from the webserver thread to the polling loop thread?
  • "This is a perfect case for a global." Oh wait, that's mutation.
  • How should we structure the app? The main function must:
    • start the thread for the web server
    • start the thread for the polling loop
  • Specific problem: the /search route handler function needs a way to send the new query string to the polling loop.
  • With mutation: share an atom and give the handler and the polling loop a reference to it.
  • No mutation? Use a core.async channel.
  • A channel allows a thread to pass data to another thread.
  • With no channel buffer, it will synchronize two threads ("rendezvous").
  • (We lie. There is no peek function.)
  • Problem: polling thread is stuck waiting on the channel, so it stops polling.
  • Solution: Use alt!! to simultaneously listen to the "new search" channel and a timeout channel.
  • What is a timeout channel? A channel that closes after n msecs have passed.
  • New problem: the cache (for de-duplicating) has stale content after changing the query.
  • Solution: same logic that adopts the new search term will reset the cache. (See Ep 007.)
  • Polling loop structure:
    1. fetch
    2. process results
    3. block while listening to the channels
    4. if new search string, recur with new cache and new search string
    5. otherwise, recur with same cache and search string
  • Only want the fetch in one part of the loop.
  • Don't even need curl. Just type in the URL for the backend on your phone.
  • core.async lets threads coordinate without having to know about each other!

Clojure in this episode:

  • atom
  • loop, recur
  • core.async/
    • chan
    • , <, >!, >>!, put!
    • alt!, alts!
    • timeout

Related projects:

  continue reading

118 episodes

Artwork
iconShare
 
Manage episode 224136429 series 2463849
Content provided by Christoph Neumann and Nate Jones, Christoph Neumann, and Nate Jones. All podcast content including episodes, graphics, and podcast descriptions are uploaded and provided directly by Christoph Neumann and Nate Jones, Christoph Neumann, and Nate Jones or their podcast platform partner. If you believe someone is using your copyrighted work without your permission, you can follow the process outlined here https://player.fm/legal.

Nate can't decide what to watch on Twitter, and the app restarts are killing him.

  • The Twitterthon continues. "It's an infinite stream of Twitter."
  • Nate wants to watch #clojurescript too.
  • Just change the search string to "#clojure OR #clojurescript"?
  • Should avoid hardcoding the value so we don't have to recompile every time.
  • Command line argument still requires a restart.
  • Let's use a curl UI (like Ep 004)!
  • Wait, what?! Why curl?
    • Can send something into the running process
    • Can separate out the client
    • Builds on top of HTTP, so there are lots of tools for testing (like curl itself)
  • Use a URL query string: http://localhost:8000/search?The+search+string
  • "It's a true query string in the truest sense of the term 'query.'"
  • "It is actually using the thing for the thing it was meant to be."
  • How do we get the query string from the webserver thread to the polling loop thread?
  • "This is a perfect case for a global." Oh wait, that's mutation.
  • How should we structure the app? The main function must:
    • start the thread for the web server
    • start the thread for the polling loop
  • Specific problem: the /search route handler function needs a way to send the new query string to the polling loop.
  • With mutation: share an atom and give the handler and the polling loop a reference to it.
  • No mutation? Use a core.async channel.
  • A channel allows a thread to pass data to another thread.
  • With no channel buffer, it will synchronize two threads ("rendezvous").
  • (We lie. There is no peek function.)
  • Problem: polling thread is stuck waiting on the channel, so it stops polling.
  • Solution: Use alt!! to simultaneously listen to the "new search" channel and a timeout channel.
  • What is a timeout channel? A channel that closes after n msecs have passed.
  • New problem: the cache (for de-duplicating) has stale content after changing the query.
  • Solution: same logic that adopts the new search term will reset the cache. (See Ep 007.)
  • Polling loop structure:
    1. fetch
    2. process results
    3. block while listening to the channels
    4. if new search string, recur with new cache and new search string
    5. otherwise, recur with same cache and search string
  • Only want the fetch in one part of the loop.
  • Don't even need curl. Just type in the URL for the backend on your phone.
  • core.async lets threads coordinate without having to know about each other!

Clojure in this episode:

  • atom
  • loop, recur
  • core.async/
    • chan
    • , <, >!, >>!, put!
    • alt!, alts!
    • timeout

Related projects:

  continue reading

118 episodes

All episodes

×
 
Loading …

Welcome to Player FM!

Player FM is scanning the web for high-quality podcasts for you to enjoy right now. It's the best podcast app and works on Android, iPhone, and the web. Signup to sync subscriptions across devices.

 

Quick Reference Guide