Episode 009: Channeling Re-search
► Play EpisodeNate 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
#clojurescripttoo. - 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
curlUI (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
curlitself)
- 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
mainfunction must:- start the thread for the web server
- start the thread for the polling loop
- Specific problem: the
/searchroute handler function needs a way to send the new query string to the polling loop. - With mutation: share an
atomand give the handler and the polling loop a reference to it. - No mutation? Use a
core.asyncchannel. - 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
peekfunction.) - 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 atimeoutchannel. - What is a
timeoutchannel? A channel that closes afternmsecs 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:
- fetch
- process results
- block while listening to the channels
- if new search string, recur with new cache and new search string
- 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.asynclets threads coordinate without having to know about each other!
Clojure in this episode:
atomloop,recurcore.async/chan<!,<<!,>!,>>!,put!alt!,alts!timeout
Related projects: