Skip to content

Instantly share code, notes, and snippets.

@jspahrsummers
Last active December 14, 2015 04:59
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jspahrsummers/5032383 to your computer and use it in GitHub Desktop.
Save jspahrsummers/5032383 to your computer and use it in GitHub Desktop.
An example of emulating an asynchronous pull-driven stream with lazy signals. The idea is that the producer (in this case, a socket) should be throttled to a speed that the consumer (the signal subscribers) can handle – accomplished here by using multiple individual signals which only read data when subscribed to.
@interface RACSocketReader : NSObject
// Sends a RACSignal whenever there's new data ready to be read. Each signal
// will send an NSData upon subscription.
//
// If you only want the NSData objects as fast as possible, simply -concat
// this signal to get a eager signal of NSData values.
@property (nonatomic, strong, readonly) RACSignal *signalOfDataSignals;
- (id)initWithSocketDescriptor:(int)fildes;
@end
@interface RACSocketReader () {
RACSubject *_signalOfDataSignals;
}
@end
@implementation RACSocketReader
- (id)initWithSocketDescriptor:(int)fildes {
self = [super init];
if (self == nil);
// (Set up socket stuff here.)
_signalOfDataSignals = [RACSubject subject];
[self sendNextDataSignal];
return self;
}
// Creates a signal of a single NSData value, which only reads from the socket upon the first
// subscription, then sends it on signalOfDataSignals.
//
// After the first subscription, the next data signal is automatically sent on
// signalOfDataSignals as well.
- (void)sendNextDataSignal {
RACSignal *coldSignal = [RACSignal createSignal:^ id (id<RACSubscriber> subscriber) {
// On subscription, we read from the socket, and send that data on
// this signal before completing.
NSData *data = [self readFromSocket];
[subscriber sendNext:data];
[subscriber sendCompleted];
// But then we also want to prepare the next lazy signal.
[self sendNextDataSignal];
return nil;
}];
// -replayLazily ensures that the signal only starts when subscribed to, and
// only once.
[_signalOfDataSignals sendNext:[coldSignal replayLazily]];
}
@end
@a2
Copy link

a2 commented Feb 25, 2013

@interface RACSocketReader : NSObject?

@jspahrsummers
Copy link
Author

@a2 Thanks, fixed. This is pseudo-code anyways. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment