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

Concurrency in Mopidy

Concurrency in Mopidy

Short presentation of how we solved concurrency in Mopidy. This is the precursor to what later became the Pykka actor library for Python. Presented at the Iterate Weekly Breakfast Meeting 2010-09-01

Stein Magnus Jodal

May 05, 2012
Tweet

More Decks by Stein Magnus Jodal

Other Decks in Programming

Transcript

  1. Mopidy is A program that connects all your music stuff,

    so that you can use it from any computer or smartphone
  2. Changes MPD server From 40% to 80% complete Now works

    98% with most MPD clients Spotify integration From 2x 50% complete to 1x 80% complete We've dropped despotify in favour of libspotify
  3. Changes License From GPLv2 to Apache License 2.0 You are

    now free to build anything on top of Mopidy Releases From 0 to 5 releases 0.1.0 released August 23 0.1.1 and 0.2.0 in the works
  4. Changes Developers From 0 to 3 active contributors Users From

    0 to 5 active users reporting bugs About 400 downloads from PyPI
  5. Changes Code More than 1100 new commits From 2700 to

    6200 lines, including tests Tests From 200 tests in 0.4s to 550 tests in 0.8s 55% of the code is tests
  6. Changes Design We still create the design as we walk

    Refactoring early and often with the confidence provided by the tests
  7. 1.Slide finger on Android or iPhone 2.Watch the volume knob

    on your NAD or Denon amplifier turn 3.Hear the sound of your music, either from Spotify or local storage
  8. We need to respond timely to clients, get data from

    Spotify, play sound, turn physical volume knobs through serial links, all at the same time
  9. Concepts Client | Frontend | Backend /------+-------\ | | |

    Spotify Output Mixer | | GStreamer ...
  10. Multiple processes respond timely to clients (frontend), get data from

    Spotify (backend) play sound (output), turn physical volume knobs through serial links (mixer), all at the same time
  11. Communication Generally, parallell processing is known to be hard to

    get right, and harder to debug. These processes are not independent, but need to communicate. How do we manage this?
  12. Solution Actors reacting to messages Multiple processes/threads (actors) that are

    working together by sending serializable messages to each other
  13. Messages A message is a command with attached data Think

    of it like a method call with arguments, which can be serialized and passed around
  14. Actors The message reactors are if/else statements (for now) def

    process_message(self, message): if message.get('to') == 'output': self.output.process_message(message) elif message.get('to') == 'frontend': for frontend in self.frontends: frontend.process_message(message) elif message['command'] == 'end_of_track': self.backends.playback.on_end_of_track() ...
  15. Loose coupling Ignorance is bliss Most of our code is

    ignorant of the concurrency. We call regular methods, which do the multiprocessing work.
  16. Loose coupling If we wanted to, we could replace said

    methods, and make the processes run on different machines Communicating over the network Nice, eh?
  17. Next release(s) Last.fm scrobbling Submit your played tracks to Last.fm

    Multi-backend Tracks from Spotify and local storage in the same playlist OS X Support intentionally broken in 0.1.0