ExpandCollapsePrev Next Index

+ 3.1 A broadcast service

As noted, if you have multiple readers and one writer, only one of the readers is sent the data. That seems like a restriction, and suggests an extension.

But no! The existing model is enough:

  gen broadcaster() : 
    oschannel[oschannel[string]] * // subscription channel
    oschannel[string]              // news reporting channel
  =
  {
    // -------------------------------------------------------------
    // SUBSCRIPTIONS
    // -------------------------------------------------------------
  
    // subscriber list
    var clients = darray[oschannel[string]] ();
  
    // subscription channel
    iregistry, oregistry := mk_ioschannel_pair[oschannel[string]]();
  
    // accept registrations
    spawn_fthread {
      while true do
        push_back (clients, read iregistry);
        println "Got a subscriber";
      done
    };
   
    // -------------------------------------------------------------
    // RELAY THE NEWS
    // -------------------------------------------------------------
  
    // news reading channel
    inews, onews := mk_ioschannel_pair[string]();
  
    // send news to all clients
    spawn_fthread {
      while true do
        news_line := read inews;
        if len clients > 0uz do
          for var i in 0uz upto len clients - 1uz do
            write$ clients.i, news_line;
          done
        done
      done
    };
  
    // return the channel for subscribing to news reports,
    // and the channel for making news reports
    return oregistry, onews;
  }
  
  // Create the broadcast station
  subscribe, news := broadcaster();
  
  // create a template for bored train commuters who want to read the news
  proc commuter (i:int) {
    ichan, ochan := mk_ioschannel_pair[string]();
    write$ subscribe, ochan; //subscribe to news
    while true do 
     line := read ichan;
     print$ "Commuter " + str i + ": " + line;
    done
  }
  
  // create two commuters
  spawn_fthread { commuter 1; };
  spawn_fthread { commuter 2; };
  
  // yield so that the commuters get a chance to subscribe
  // to the new before the broadcast begins
  // (this is a hack just to make the demo work)
  svc$ #svc_yield;
  
  // create a reporter that just sends numbers as news
  spawn_fthread {
    for var i in 0 upto 9 do
      var line = i.str + "\n";
      println$ "Reporting : " + line;
      write$ news, line;
    done
  };
  
  println$ "Demo started";