Create a gist now

Instantly share code, notes, and snippets.

@JonDouglas /beingreactive.cs Secret
Last active Jul 26, 2017

What would you like to do?
Being Reactive
void Main()
{
Random rand = new Random();
var meatsSource = Observable.Interval(TimeSpan.FromSeconds(3))
.Select(_ => new Meat() { Rotten = new Random().Next(0, 2) == 1 ? true : false })
.Do(
x => Console.WriteLine("OnNext: {0}", "Meat - Rotten: " + x.Rotten),
ex => Console.WriteLine("OnError: {0}", ex.Message),
() => Console.WriteLine("OnCompleted: {0}", "Meats"))
.Where(meat => !meat.Rotten)
.Publish()
.RefCount();
var cookedMeatsSource = meatsSource.Select(meat => Cook(meat)).Do(
x => Console.WriteLine("OnNext: {0}", "Meat - Cooked: " + x.Cooked),
ex => Console.WriteLine("OnError: {0}", ex.Message),
() => Console.WriteLine("OnCompleted: {0}", "Cooked Meats"))
.Publish()
.RefCount();
var bunsSource = Observable.Interval(TimeSpan.FromSeconds(5))
.Select(_ => Heat(new Bun()))
.Do(
x => Console.WriteLine("OnNext: {0}", "Bun - Heated: " + x.Heated),
ex => Console.WriteLine("OnError: {0}", ex.Message),
() => Console.WriteLine("OnCompleted: {0}", "Buns"))
.Publish()
.RefCount();
var lettuceSource = Observable.Interval(TimeSpan.FromSeconds(2))
.Select(_ => new Lettuce())
.Do(
x => Console.WriteLine("OnNext: {0}", "Lettuce - Fresh: " + x.Fresh),
ex => Console.WriteLine("OnError: {0}", ex.Message),
() => Console.WriteLine("OnCompleted: {0}", "Lettuce"))
.Publish()
.RefCount();
var hamburgerSource =
Observable.Zip(cookedMeatsSource, bunsSource, lettuceSource, (meat, bun, lettuce) => new Hamburger { Meat = meat, Bun = bun, Lettuce = lettuce })
.Do(x => Console.WriteLine("OnNext: {0}", "Hamburger - Meat Cooked: " + x.Meat.Cooked + " || Bun Heated: " + x.Bun.Heated + " || Lettuce Fresh: " + x.Lettuce.Fresh),
ex => Console.WriteLine("OnError: {0}", ex.Message),
() => Console.WriteLine("OnCompleted: {0}", "Hamburgers"))
.Publish()
.RefCount();
Console.WriteLine("Family BBQ - Start!");
hamburgerSource.Subscribe();
}
public class Hamburger
{
public Meat Meat { get; set; }
public Lettuce Lettuce { get; set; }
public Bun Bun { get; set; }
}
public class Meat
{
public bool Cooked { get; set; }
public bool Rotten { get; set; }
}
public class Lettuce
{
public bool Fresh { get; set; } = true;
}
public class Bun
{
public bool Heated { get; set; }
}
public Meat Cook(Meat meat)
{
meat.Cooked = true;
return meat;
}
public Bun Heat(Bun bun)
{
bun.Heated = true;
return bun;
}

Fun idea

One thought would be to use Publish/RefCount on the sources so they are the same streams. For example "meatsSource" currently will be subscribed to three different times (if I counted that right) so what's being logged I don't think is technically what makes it to the end. If you log the n from the zip

.Zip(meats.Where(m => m.Rotten.Equals(false)), (n, m) => m);

You'll see 3 of each count showing up

Using a Logging extension might help clarity
https://github.com/LeeCampbell/RxCookbook/blob/master/Instrumentation/Logging.md

It's the one time you can have a Do and you won't get yelled at :-p

so something like

var meatsSource = Observable.Interval(TimeSpan.FromSeconds(3))
               .DoOrLogging
		.Zip(meats.Where(m => m.Rotten.Equals(false)), (n, m) => m);
               .PublishRefCount()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment