title: How to conditionally buffer RACSignal values?
body: <p>I'm working on some code that interacts with a remote API via websockets.  My data layer is responsible for establishing and monitoring the websocket connection.  It also contains methods that can be used by the application to enqueue websocket messages to be sent.  The application code should not be responsible for inspecting the state of the websocket connection, aka fire-and-forget.</p>
  
  <p>Ideally, I'd like to data layer to function as follows:</p>
  
  <ul>
  <li>When the data layer does not have a connection to the websocket endpoint (<code>self.isConnected == NO</code>), messages are buffered internally.</li>
  <li>When a connection is becomes available (<code>self.isConnected == YES</code>), buffered messages are immediately sent, and any subsequent messages are sent immediately.</li>
  </ul>
  
  <p>Here's what I've been able to come up with:</p>
  
  <pre><code>#import "RACSignal+Buffering.h"
  
  @implementation RACSignal (Buffering)
  
  - (RACSignal*)bufferWithSignal:(RACSignal*)shouldBuffer
  {
      return [RACSignal createSignal:^RACDisposable *(id&lt;RACSubscriber&gt; subscriber) {
  
          RACCompoundDisposable *disposable = [RACCompoundDisposable compoundDisposable];
  
          NSMutableArray* bufferedValues = [[NSMutableArray alloc] init];
          __block BOOL buffering = NO;
  
          void (^bufferHandler)() = ^{
              if (!buffering)
              {
                  for (id val in bufferedValues)
                  {
                      [subscriber sendNext:val];
                  }
  
                  [bufferedValues removeAllObjects];
              }
          };
  
          RACDisposable* bufferDisposable = [shouldBuffer subscribeNext:^(NSNumber* shouldBuffer) {
  
              buffering = shouldBuffer.boolValue;
              bufferHandler();
  
          }];
  
          if (bufferDisposable)
          {
              [disposable addDisposable:bufferDisposable];
          }
  
          RACDisposable* valueDisposable = [self subscribeNext:^(id x) {
  
              [bufferedValues addObject:x];
              bufferHandler();
  
          } error:^(NSError *error) {
              [subscriber sendError:error];
          } completed:^{
              [subscriber sendCompleted];
          }];
  
          if (valueDisposable)
          {
              [disposable addDisposable:valueDisposable];
          }
  
          return disposable;
      }];
  }
  
  @end
  </code></pre>
  
  <p>Lastly, this is pseudo-code for how it would be used:</p>
  
  <pre><code>@interface APIManager ()
  
  @property (nonatomic) RACSubject* requests;
  
  @end
  
  @implementation WebsocketDataLayer
  
  - (id)init
  {
      self = [super init];
  
      if (self) {
  
          RACSignal* connectedSignal = RACObserve(self, connected);
  
          self.requests = [[RACSubject alloc] init];
  
          RACSignal* bufferedApiRequests = [self.requests bufferWithSignal:connectedSignal];
  
          [self rac_liftSelector:@selector(sendRequest:) withSignalsFromArray:@[bufferedApiRequests]];
      }
      return self;
  }
  
  - (void)enqueueRequest:(NSString*)request
  {
      [self.requests sendNext:request];
  }
  
  - (void)sendRequest:(NSString*)request
  {
      DebugLog(@"Making websocket request: %@", request);
  }
  
  @end
  </code></pre>
  
  <p>My question is: Is this the right approach for buffering values? Is there a more idiomatic RAC way of handling this?</p>