programação reativa e o actor model

Post on 09-Feb-2017

56 Views

Category:

Software

2 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Programação Reativa e o Actor Model

Elemar Júnior@elemarjr

elemarjr@ravendb.netelemarjr@gmail.com

elemarjr.com

Olá, eu sou Elemar Jr

Abstrações...

Antes de entender o que é Programação Reativa, vamos

entender o que não é!

public static string[] GetNamesFromEmployees(Employee[] employees){ var result = new string[employees.Length]; for (var i = 0; i < employees.Length; i++) { result[i] = employees[i].Name; } return result;}

public static string[] GetNamesFromEmployees(Employee[] employees){ var result = new string[employees.Length]; for (var i = 0; i < employees.Length; i++) { result[i] = employees[i].Name; } return result;}

public static List<string> GetNamesFromEmployees(List<Employee> employees){ var result = new List<string>(employees.Count); foreach (var employee in employees) { result.Add(employee.Name); } return result;}

public static IList<string> GetNamesFromEmployees(IList<Employee> employees){ var result = new List<string>(employees.Count); foreach (var employee in employees) { result.Add(employee.Name); } return result;}

public static IEnumerable<string> GetNamesFromEmployees(IEnumerable<Employee> employees){ var result = new List<string>(); foreach (var employee in employees) { result.Add(employee.Name); } return result;}

public static IEnumerable<string> GetNamesFromEmployees(IEnumerable<Employee> employees){ var result = new List<string>(); foreach (var employee in employees) { result.Add(employee.Name); } return result;}

public static IEnumerable<string> GetNamesFromEmployees(IEnumerable<Employee> employees){ foreach (var employee in employees) { yield return employee.Name; }}

PAUSA PARA ENTENDER...

using System.Collections.Generic;using static System.Console;

public class Program{ public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } }

public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } }}

using System.Collections.Generic;using static System.Console;

public class Program{ public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } }

public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } }}

Before calling Get4

using System.Collections.Generic;using static System.Console;

public class Program{ public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } }

public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } }}

Before calling Get4

using System.Collections.Generic;using static System.Console;

public class Program{ public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } }

public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } }}

Before calling Get4After calling Get4

using System.Collections.Generic;using static System.Console;

public class Program{ public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } }

public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } }}

Before calling Get4After calling Get4

using System.Collections.Generic;using static System.Console;

public class Program{ public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } }

public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } }}

Before calling Get4After calling Get4

using System.Collections.Generic;using static System.Console;

public class Program{ public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } }

public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } }}

Before calling Get4After calling Get4

using System.Collections.Generic;using static System.Console;

public class Program{ public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } }

public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } }}

Before calling Get4After calling Get4

using System.Collections.Generic;using static System.Console;

public class Program{ public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } }

public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } }}

Before calling Get4After calling Get4

using System.Collections.Generic;using static System.Console;

public class Program{ public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } }

public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } }}

Before calling Get4After calling Get4Before Yield 1

using System.Collections.Generic;using static System.Console;

public class Program{ public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } }

public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } }}

Before calling Get4After calling Get4Before Yield 1

using System.Collections.Generic;using static System.Console;

public class Program{ public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } }

public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } }}

Before calling Get4After calling Get4Before Yield 1

using System.Collections.Generic;using static System.Console;

public class Program{ public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } }

public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } }}

Before calling Get4After calling Get4Before Yield 1

using System.Collections.Generic;using static System.Console;

public class Program{ public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } }

public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } }}

Before calling Get4After calling Get4Before Yield 11

using System.Collections.Generic;using static System.Console;

public class Program{ public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } }

public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } }}

Before calling Get4After calling Get4Before Yield 11

using System.Collections.Generic;using static System.Console;

public class Program{ public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } }

public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } }}

Before calling Get4After calling Get4Before Yield 11

using System.Collections.Generic;using static System.Console;

public class Program{ public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } }

public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } }}

Before calling Get4After calling Get4Before Yield 11After Yield 1

using System.Collections.Generic;using static System.Console;

public class Program{ public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } }

public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } }}

Before calling Get4After calling Get4Before Yield 11After Yield 1Before Yield 2

using System.Collections.Generic;using static System.Console;

public class Program{ public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } }

public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } }}

Before calling Get4After calling Get4Before Yield 11After Yield 1Before Yield 2

...

VOLTAMOS...

public static IEnumerable<string> GetNamesFromEmployees(IEnumerable<Employee> employees){ foreach (var employee in employees) { yield return employee.Name; }}

public static class EnumerableOfEmployees{ public static IEnumerable<string> GetNames(IEnumerable<Employee> employees) { foreach (var employee in employees) { yield return employee.Name; } }}

EnumerableOfEmployees.GetNames(someListOfEmployees);

public static class EnumerableOfEmployees{ public static IEnumerable<string> GetNames( this IEnumerable<Employee> employees ) { foreach (var employee in employees) { yield return employee.Name; } }}

var names = someListOfEmployees.GetNames();

var names = EnumerableOfEmployees.GetNames(someListOfEmployees);

public static class EnumerableOfEmployees{ public static IEnumerable<string> GetNames( this IEnumerable<Employee> employees ) { foreach (var employee in employees) { yield return employee.Name; } }

public static IEnumerable<string> GetSocialSecurityNumbers( this IEnumerable<Employee> employees ) { foreach (var employee in employees) { yield return employee.SocialSecurityNumber; } }}

public static class EnumerableOfEmployees{ public static IEnumerable<string> GetNames( this IEnumerable<Employee> employees ) { foreach (var employee in employees) { yield return employee.Name; } }

public static IEnumerable<string> GetSocialSecurityNumbers( this IEnumerable<Employee> employees ) { foreach (var employee in employees) { yield return employee.SocialSecurityNumber; } }}

public static class EnumerableOfEmployees{ public static IEnumerable<TResult> Get<TResult>( this IEnumerable<Employee> employees, Func<Employee, TResult> selector ) { foreach (var employee in employees) { yield return selector(employee); } }}

var names = someListOfEmployees.Get(e => e.Name);var ssn = someListOfEmployees.Get(e => e.SocialSecurityNumber);

public static class EnumerableOfEmployees{ public static IEnumerable<TResult> Get<TResult>( this IEnumerable<Employee> employees, Func<Employee, TResult> selector ) { foreach (var employee in employees) { yield return selector(employee); } }}

public static class Enumerable{ public static IEnumerable<TResult> Get<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ) { foreach (var element in elements) { yield return selector(element); } }}

public static class Enumerable{ public static IEnumerable<TResult> Get<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ) { foreach (var element in elements) { yield return selector(element); } }}

public static class Enumerable{ public static IEnumerable<TResult> Select<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ) { foreach (var element in elements) { yield return selector(element); } }}

LINQPara objetos em memória

public static class Enumerable{ public static IEnumerable<TResult> Select<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ) { foreach (var element in elements) { yield return selector(element); } }}

var names = someListOfEmployees.Select(e => e.Name);var ssn = someListOfEmployees.Select(e => e.SocialSecurityNumber);

public static IEnumerable<T> Where<T>( this IEnumerable<T> elements, Func<T, bool> filter){ foreach (var element in elements) { if (filter(element)) { yield return element; } }}

public static IEnumerable<T> Take<T>( this IEnumerable<T> elements, int count){ var i = 0; foreach (var element in elements) { if (i >= count) yield break; yield return element; i++; }}

public static class Enumerable{ public static IEnumerable<TResult> Select<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ) { foreach (var element in elements) { yield return selector(element); } }}

public interface IEnumerable<out T> : IEnumerable{ IEnumerator<T> GetEnumerator();}

public static class Enumerable{ public static IEnumerable<TResult> Select<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ) { foreach (var element in elements) { yield return selector(element); } }}

public interface IEnumerable<out T> : IEnumerable{ IEnumerator<T> GetEnumerator();}public interface IEnumerator<out T> : IDisposable, IEnumerator{ T Current { get; }}

public static class Enumerable{ public static IEnumerable<TResult> Select<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ) { foreach (var element in elements) { yield return selector(element); } }}

public interface IEnumerable<out T> : IEnumerable{ IEnumerator<T> GetEnumerator();}public interface IEnumerator<out T> : IDisposable, IEnumerator{ T Current { get; }}public interface IEnumerator{ object Current { get; } bool MoveNext(); void Reset();}

public static IEnumerable<TResult> Select<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ){ using (var enumerator = elements.GetEnumerator()) { while (enumerator.MoveNext()) { yield return selector(enumerator.Current); } }}

public static IEnumerable<TResult> Select<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ){ using (var enumerator = elements.GetEnumerator()) { while (enumerator.MoveNext()) { yield return selector(enumerator.Current); } }}

public interface IEnumerable<out T> : IEnumerable{ IEnumerator<T> GetEnumerator();}public interface IEnumerator<out T> : IDisposable, IEnumerator{ T Current { get; }}public interface IEnumerator{ object Current { get; } bool MoveNext(); void Reset();}

public static IEnumerable<TResult> Select<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ){ using (var enumerator = elements.GetEnumerator()) { while (enumerator.MoveNext()) { yield return selector(enumerator.Current); } }}

public interface IEnumerable<out T> : IEnumerable{ IEnumerator<T> GetEnumerator();}public interface IEnumerator<out T> : IDisposable, IEnumerator{ T Current { get; }}public interface IEnumerator{ object Current { get; } bool MoveNext(); void Reset();}

public static IEnumerable<TResult> Select<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ){ using (var enumerator = elements.GetEnumerator()) { while (enumerator.MoveNext()) { yield return selector(enumerator.Current); } }}

public interface IEnumerable<out T> : IEnumerable{ IEnumerator<T> GetEnumerator();}public interface IEnumerator<out T> : IDisposable, IEnumerator{ T Current { get; }}public interface IEnumerator{ object Current { get; } bool MoveNext(); void Reset();}

public static IEnumerable<TResult> Select<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ){ using (var enumerator = elements.GetEnumerator()) { while (enumerator.MoveNext()) { yield return selector(enumerator.Current); } }}

public interface IEnumerable<out T> : IEnumerable{ IEnumerator<T> GetEnumerator();}public interface IEnumerator<out T> : IDisposable, IEnumerator{ T Current { get; }}public interface IEnumerator{ object Current { get; } bool MoveNext(); void Reset();}

public static IEnumerable<TResult> Select<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ){ using (var enumerator = elements.GetEnumerator()) { while (enumerator.MoveNext()) { yield return selector(enumerator.Current); } }}

public interface IEnumerable<out T> : IEnumerable{ IEnumerator<T> GetEnumerator();}public interface IEnumerator<out T> : IDisposable, IEnumerator{ T Current { get; }}public interface IEnumerator{ object Current { get; } bool MoveNext(); void Reset();}

public static IEnumerable<TResult> Select<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ){ using (var enumerator = elements.GetEnumerator()) { while (enumerator.MoveNext()) { yield return selector(enumerator.Current); } }}

public static IEnumerable<TResult> Select<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ) => new SelectEnumerable<T, TResult>(elements, selector);

class SelectEnumerable<T, TResult> : IEnumerable<TResult>{ private readonly IEnumerable<T> _elements; private readonly Func<T, TResult> _selector;

public SelectEnumerable( IEnumerable<T> elements, Func<T, TResult> selector ) { _elements = elements; _selector = selector; }

public IEnumerator<TResult> GetEnumerator() => new SelectEnumerator(_elements.GetEnumerator(), _selector);

IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();}

public static IEnumerable<TResult> Select<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ) => new SelectEnumerable<T, TResult>(elements, selector);

class SelectEnumerable<T, TResult> : IEnumerable<TResult>{ private readonly IEnumerable<T> _elements; private readonly Func<T, TResult> _selector;

public SelectEnumerable( IEnumerable<T> elements, Func<T, TResult> selector ) { _elements = elements; _selector = selector; }

public IEnumerator<TResult> GetEnumerator() => new SelectEnumerator(_elements.GetEnumerator, _selector);

IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();}

class SelectEnumerator<T, TResult> : IEnumerator<TResult>{ private readonly IEnumerator<T> _source; private readonly Func<T, TResult> _selector;

public SelectEnumerator( IEnumerator<T> source, Func<T, TResult> selector ) { _source = source; _selector = selector; }

public void Dispose() => _source.Dispose(); public bool MoveNext() => _source.MoveNext(); public void Reset() => _source.Dispose(); public TResult Current => _selector(_source.Current); object IEnumerator.Current => Current;}

var names = someEmployees.Select(e => e.Name);foreach (var name in names){ Console.WriteLine(name);}

var names = someEmployees.Select(e => e.Name);using (var enumerator = names.GetEnumerator()){ while (enumerator.MoveNext()) { Console.WriteLine(enumerator.Current); }}

var names = someEmployees.Select(e => e.Name);using (var enumerator = names.GetEnumerator()){ while (enumerator.MoveNext()) { Console.WriteLine(enumerator.Current); }}

var names = someEmployees.Select(e => e.Name);using (var enumerator = names.GetEnumerator()){ while (enumerator.MoveNext()) { Console.WriteLine(enumerator.Current); }}

public static IEnumerable<TResult> Select<T, TResult>( this IEnumerable<T> elements, Func<T, TResult> selector ) => new SelectEnumerable<T, TResult>(elements, selector);

var names = someEmployees.Select(e => e.Name);using (var enumerator = names.GetEnumerator()){ while (enumerator.MoveNext()) { Console.WriteLine(enumerator.Current); }}

var names = someEmployees.Select(e => e.Name);using (var enumerator = names.GetEnumerator()){ while (enumerator.MoveNext()) { Console.WriteLine(enumerator.Current); }}

class SelectEnumerable<T, TResult> : IEnumerable<TResult>{ private readonly IEnumerable<T> _elements; private readonly Func<T, TResult> _selector;

public SelectEnumerable( IEnumerable<T> elements, Func<T, TResult> selector ) { _elements = elements; _selector = selector; }

public IEnumerator<TResult> GetEnumerator() => new SelectEnumerator(_elements.GetEnumerator, _selector);

IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();}

var names = someEmployees.Select(e => e.Name);using (var enumerator = names.GetEnumerator()){ while (enumerator.MoveNext()) { Console.WriteLine(enumerator.Current); }}

class SelectEnumerator<T, TResult> : IEnumerator<TResult>{ private readonly IEnumerator<T> _source; private readonly Func<T, TResult> _selector;

public SelectEnumerator( IEnumerator<T> source, Func<T, TResult> selector ) { _source = source; _selector = selector; }

public void Dispose() => _source.Dispose(); public bool MoveNext() => _source.MoveNext(); public void Reset() => _source.Dispose(); public TResult Current => _selector(_source.Current); object IEnumerator.Current => Current;}

var names = someEmployees.Select(e => e.Name);using (var enumerator = names.GetEnumerator()){ while (enumerator.MoveNext()) { Console.WriteLine(enumerator.Current); }}

class SelectEnumerator<T, TResult> : IEnumerator<TResult>{ private readonly IEnumerator<T> _source; private readonly Func<T, TResult> _selector;

public SelectEnumerator( IEnumerator<T> source, Func<T, TResult> selector ) { _source = source; _selector = selector; }

public void Dispose() => _source.Dispose(); public bool MoveNext() => _source.MoveNext(); public void Reset() => _source.Dispose(); public TResult Current => _selector(_source.Current); object IEnumerator.Current => Current;}

var names = someEmployees.Select(e => e.Name);using (var enumerator = names.GetEnumerator()){ while (enumerator.MoveNext()) { Console.WriteLine(enumerator.Current); }}

class SelectEnumerator<T, TResult> : IEnumerator<TResult>{ private readonly IEnumerator<T> _source; private readonly Func<T, TResult> _selector;

public SelectEnumerator( IEnumerator<T> source, Func<T, TResult> selector ) { _source = source; _selector = selector; }

public void Dispose() => _source.Dispose(); public bool MoveNext() => _source.MoveNext(); public void Reset() => _source.Dispose(); public TResult Current => _selector(_source.Current); object IEnumerator.Current => Current;}

var names = someEmployees.Select(e => e.Name);using (var enumerator = names.GetEnumerator()){ while (enumerator.MoveNext()) { Console.WriteLine(enumerator.Current); }}

class SelectEnumerator<T, TResult> : IEnumerator<TResult>{ private readonly IEnumerator<T> _source; private readonly Func<T, TResult> _selector;

public SelectEnumerator( IEnumerator<T> source, Func<T, TResult> selector ) { _source = source; _selector = selector; }

public void Dispose() => _source.Dispose(); public bool MoveNext() => _source.MoveNext(); public void Reset() => _source.Dispose(); public TResult Current => _selector(_source.Current); object IEnumerator.Current => Current;}

var names = someEmployees.Select(e => e.Name);using (var enumerator = names.GetEnumerator()){ while (enumerator.MoveNext()) { Console.WriteLine(enumerator.Current); }}

class SelectEnumerator<T, TResult> : IEnumerator<TResult>{ private readonly IEnumerator<T> _source; private readonly Func<T, TResult> _selector;

public SelectEnumerator( IEnumerator<T> source, Func<T, TResult> selector ) { _source = source; _selector = selector; }

public void Dispose() => _source.Dispose(); public bool MoveNext() => _source.MoveNext(); public void Reset() => _source.Dispose(); public TResult Current => _selector(_source.Current); object IEnumerator.Current => Current;}

var names = someEmployees.Select(e => e.Name);using (var enumerator = names.GetEnumerator()){ while (enumerator.MoveNext()) { Console.WriteLine(enumerator.Current); }}

class SelectEnumerator<T, TResult> : IEnumerator<TResult>{ private readonly IEnumerator<T> _source; private readonly Func<T, TResult> _selector;

public SelectEnumerator( IEnumerator<T> source, Func<T, TResult> selector ) { _source = source; _selector = selector; }

public void Dispose() => _source.Dispose(); public bool MoveNext() => _source.MoveNext(); public void Reset() => _source.Dispose(); public TResult Current => _selector(_source.Current); object IEnumerator.Current => Current;}

class WhereEnumerator<T> : IEnumerator<T>{ private readonly IEnumerator<T> _source; private readonly Func<T, bool> _filter;

public WhereEnumerator( IEnumerator<T> source, Func<T, bool> filter ) { _source = source; _filter = filter; }

public void Dispose() => _source.Dispose();

public bool MoveNext() { while (_source.MoveNext()) if (_filter(_source.Current)) return true;

return false; }

public void Reset() => _source.Reset(); public T Current => _source.Current; object IEnumerator.Current => Current;}

class WhereEnumerator<T> : IEnumerator<T>{ private readonly IEnumerator<T> _source; private readonly Func<T, bool> _filter;

public WhereEnumerator( IEnumerator<T> source, Func<T, bool> filter ) { _source = source; _filter = filter; }

public void Dispose() => _source.Dispose();

public bool MoveNext() { while (_source.MoveNext()) if (_filter(_source.Current)) return true;

return false; }

public void Reset() => _source.Reset(); public T Current => _source.Current; object IEnumerator.Current => Current;}

class SelectEnumerator<T, TResult> : IEnumerator<TResult>{ private readonly IEnumerator<T> _source; private readonly Func<T, TResult> _selector;

public SelectEnumerator( IEnumerator<T> source, Func<T, TResult> selector ) { _source = source; _selector = selector; }

public void Dispose() => _source.Dispose(); public bool MoveNext() => _source.MoveNext(); public void Reset() => _source.Dispose(); public TResult Current => _selector(_source.Current); object IEnumerator.Current => Current;}

PAUSA PARA ENTENDER...

using System.Collections.Generic;using static System.Console;

public class Program{ public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } }

public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } }}

public static IEnumerable<int> Get4() => new Get4Enumerable();

using System.Collections.Generic;using static System.Console;

public class Program{ public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } }

public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } }}

using (var enumerator = elements.GetEnumerator()){ while (enumerator.MoveNext()) { WriteLine(enumerator.Current); }}

using System.Collections.Generic;using static System.Console;

public class Program{ public static void Main() { WriteLine("Before calling Get4"); var elements = Get4(); WriteLine("After calling Get4"); foreach (var e in elements) { WriteLine(e); } }

public static IEnumerable<int> Get4() { for (var i = 1; i <= 4; i++) { WriteLine($"Before Yield {i}"); yield return i; WriteLine($"After Yield {i}"); } }}

class Get4Enumerator : IEnumerator<int>{ private int _state; private int _current; public void Dispose() { } bool IEnumerator.MoveNext() { if (_state == 1) WriteLine($"After Yield {_current}"); if (_current >= 4) { _state = 2; return false; }

_current++; WriteLine($"Before Yield {_current}"); _state = 1; return true; }

public void Reset() { _current = 0; } public int Current => _current; object IEnumerator.Current => Current;}

VOLTAMOS...

Where Select ConsumerProducer

Where Select ConsumerProducer

GetEnumerator()

using (var enumerator = elements.GetEnumerator()){ while (enumerator.MoveNext()) { WriteLine(enumerator.Current); }}

Where Select ConsumerProducer

GetEnumerator()GetEnumerator()

using (var enumerator = elements.GetEnumerator()){ while (enumerator.MoveNext()) { WriteLine(enumerator.Current); }}

Where Select ConsumerProducer

GetEnumerator()GetEnumerator()GetEnumerator()

using (var enumerator = elements.GetEnumerator()){ while (enumerator.MoveNext()) { WriteLine(enumerator.Current); }}

Where Select ConsumerProducer

MoveNext()

using (var enumerator = elements.GetEnumerator()){ while (enumerator.MoveNext()) { WriteLine(enumerator.Current); }}

Where Select ConsumerProducer

MoveNext()MoveNext()

using (var enumerator = elements.GetEnumerator()){ while (enumerator.MoveNext()) { WriteLine(enumerator.Current); }}

Where Select ConsumerProducer

MoveNext()MoveNext()MoveNext()

using (var enumerator = elements.GetEnumerator()){ while (enumerator.MoveNext()) { WriteLine(enumerator.Current); }}

Consumidor Comanda

Estamos habituados a desenvolver código “pró-ativo”

Mas por que se fala tanto em programação “reativa”?

Usuários esperam resultados em real-time

Eventos são cidadãos de primeira grandeza.

Eventos são cidadãos de primeira grandezaUser Interface

Eventos são cidadãos de primeira grandezaDomain Events

Eventos são cidadãos de primeira grandeza

Infrastructure Events

Eventos são cidadãos de primeira grandeza

Integration Events (Bus)

Erik Meijer

Where Select ConsumerProducer

IEnumerableIEnumerableIEnumerable

Where Select ConsumerProducer

IEnumerableIEnumerableIEnumerableIObservableIObservableIObservable

Where Select ConsumerProducer

IEnumerableIEnumerableIEnumerableIObservableIObservableIObservable

public interface IObservable<out T>{ IDisposable Subscribe(IObserver<T> observer);}

Where Select ConsumerProducer

IEnumerableIEnumerableIEnumerableIObservableIObservableIObservable

public interface IObservable<out T>{ IDisposable Subscribe(IObserver<T> observer);}

IObserver

IObserverIObserver

public interface IObserver<in T>{ void OnCompleted(); void OnError(Exception error); void OnNext(T value);}

Where Select ConsumerProducer

Subscribe()

Where Select ConsumerProducer

Subscribe()Subscribe()

Where Select ConsumerProducer

Subscribe()Subscribe()Subscribe()

Where Select ConsumerProducer

OnNext/OnError/OnCompleted OnNext/OnError/OnCompleted OnNext/OnError/OnCompleted

Where Select ConsumerProducer

OnNext/OnError/OnCompleted OnNext/OnError/OnCompleted OnNext/OnError/OnCompleted

Produtor Comanda

Exemplo 1: Abstrações para APIs primitivas

public class Bytes : IObservable<byte>{ private readonly NetworkStream _stream; private readonly Subject<byte> _subject;

private Bytes(NetworkStream stream) { _stream = stream; _subject = new Subject<byte>(); }

private bool _running; private async void Run() { _running = true; var buffer = new byte[8192]; try { int bytesRead; while ((bytesRead = await _stream.ReadAsync(buffer, 0, buffer.Length)) != 0) for (var i = 0; i < bytesRead; i++) _subject.OnNext(buffer[i]);

} catch (Exception e) { _subject.OnError(e); } _subject.OnCompleted(); }

private readonly object _guard = new object(); public IDisposable Subscribe(IObserver<byte> observer) { lock (_guard) { var result = _subject.Subscribe(observer); if (!_running) Run(); return result; } }

public static Bytes From(NetworkStream stream) => new Bytes(stream);}

public class Bytes : IObservable<byte>{ private readonly NetworkStream _stream; private readonly Subject<byte> _subject;

private Bytes(NetworkStream stream) { _stream = stream; _subject = new Subject<byte>(); }

public class Bytes : IObservable<byte>{ private readonly NetworkStream _stream; private readonly Subject<byte> _subject;

private Bytes(NetworkStream stream) { _stream = stream; _subject = new Subject<byte>(); }

private bool _running; private async void Run() { _running = true; var buffer = new byte[8192]; try { int bytesRead; while ((bytesRead = await _stream.ReadAsync(buffer, 0, buffer.Length)) != 0) for (var i = 0; i < bytesRead; i++) _subject.OnNext(buffer[i]);

} catch (Exception e) { _subject.OnError(e); } _subject.OnCompleted(); }

private readonly object _guard = new object(); public IDisposable Subscribe(IObserver<byte> observer) { lock (_guard) { var result = _subject.Subscribe(observer); if (!_running) Run(); return result; } }

public static Bytes From(NetworkStream stream) => new Bytes(stream);}

private readonly object _guard = new object();public IDisposable Subscribe(IObserver<byte> observer){ lock (_guard) { var result = _subject.Subscribe(observer); if (!_running) Run(); return result; }}

public static Bytes From(NetworkStream stream) => new Bytes(stream);

public class Bytes : IObservable<byte>{ private readonly NetworkStream _stream; private readonly Subject<byte> _subject;

private Bytes(NetworkStream stream) { _stream = stream; _subject = new Subject<byte>(); }

private bool _running; private async void Run() { _running = true; var buffer = new byte[8192]; try { int bytesRead; while ((bytesRead = await _stream.ReadAsync(buffer, 0, buffer.Length)) != 0) for (var i = 0; i < bytesRead; i++) _subject.OnNext(buffer[i]);

} catch (Exception e) { _subject.OnError(e); } _subject.OnCompleted(); }

private readonly object _guard = new object(); public IDisposable Subscribe(IObserver<byte> observer) { lock (_guard) { var result = _subject.Subscribe(observer); if (!_running) Run(); return result; } }

public static Bytes From(NetworkStream stream) => new Bytes(stream);}

private bool _running;private async void Run(){ _running = true; var buffer = new byte[8192]; try { int bytesRead; while ((bytesRead = await _stream.ReadAsync(buffer, 0, buffer.Length)) != 0) { for (var i = 0; i < bytesRead; i++) _subject.OnNext(buffer[i]); } } catch (Exception e) { _subject.OnError(e); }

_subject.OnCompleted();}

public class FramedMessages : IObservable<string>{ enum States {Expecting254, Expecting255 };

private readonly Subject<string> _subject; private FramedMessages(IObservable<byte> bytes) { _subject = new Subject<string>(); var buffer = new MemoryStream(); var currentState = States.Expecting254;

bytes.Subscribe(new AnonymousObserver<byte>( onNext: b => { if (currentState == States.Expecting254) { if (b == 254) currentState = States.Expecting255; else buffer.WriteByte(b); } else { if (b == 255) { currentState = States.Expecting254; var message = Encoding.UTF8.GetString(buffer.ToArray()); _subject.OnNext(message); buffer = new MemoryStream(); } else { buffer.WriteByte(254); buffer.WriteByte(255); } } }, onCompleted: () => { var a = buffer.ToArray(); if (a.Length != 0) { var message = Encoding.UTF8.GetString(buffer.ToArray()); _subject.OnNext(message); } _subject.OnCompleted(); } )); }

public IDisposable Subscribe(IObserver<string> observer) => _subject.Subscribe(observer);

public static FramedMessages From(IObservable<byte> bytes) => new FramedMessages(bytes);}

public class FramedMessages : IObservable<string>{ enum States { Expecting254, Expecting255 };

private readonly Subject<string> _subject; private FramedMessages(IObservable<byte> bytes) { _subject = new Subject<string>(); var buffer = new MemoryStream(); var currentState = States.Expecting254;

public class FramedMessages : IObservable<string>{ enum States {Expecting254, Expecting255 };

private readonly Subject<string> _subject; private FramedMessages(IObservable<byte> bytes) { _subject = new Subject<string>(); var buffer = new MemoryStream(); var currentState = States.Expecting254;

bytes.Subscribe(new AnonymousObserver<byte>( onNext: b => { if (currentState == States.Expecting254) { if (b == 254) currentState = States.Expecting255; else buffer.WriteByte(b); } else { if (b == 255) { currentState = States.Expecting254; var message = Encoding.UTF8.GetString(buffer.ToArray()); _subject.OnNext(message); buffer = new MemoryStream(); } else { buffer.WriteByte(254); buffer.WriteByte(255); } } }, onCompleted: () => { var a = buffer.ToArray(); if (a.Length != 0) { var message = Encoding.UTF8.GetString(buffer.ToArray()); _subject.OnNext(message); } _subject.OnCompleted(); } )); }

public IDisposable Subscribe(IObserver<string> observer) => _subject.Subscribe(observer);

public static FramedMessages From(IObservable<byte> bytes) => new FramedMessages(bytes);}

bytes.Subscribe(new AnonymousObserver<byte>( onNext: b => { if (currentState == States.Expecting254) { if (b == 254) currentState = States.Expecting255; else buffer.WriteByte(b); } else { if (b == 255) { currentState = States.Expecting254; var message = Encoding.UTF8.GetString(buffer.ToArray()); _subject.OnNext(message); buffer = new MemoryStream(); } else { buffer.WriteByte(254); buffer.WriteByte(255); } } },

public class FramedMessages : IObservable<string>{ enum States {Expecting254, Expecting255 };

private readonly Subject<string> _subject; private FramedMessages(IObservable<byte> bytes) { _subject = new Subject<string>(); var buffer = new MemoryStream(); var currentState = States.Expecting254;

bytes.Subscribe(new AnonymousObserver<byte>( onNext: b => { if (currentState == States.Expecting254) { if (b == 254) currentState = States.Expecting255; else buffer.WriteByte(b); } else { if (b == 255) { currentState = States.Expecting254; var message = Encoding.UTF8.GetString(buffer.ToArray()); _subject.OnNext(message); buffer = new MemoryStream(); } else { buffer.WriteByte(254); buffer.WriteByte(255); } } }, onCompleted: () => { var a = buffer.ToArray(); if (a.Length != 0) { var message = Encoding.UTF8.GetString(buffer.ToArray()); _subject.OnNext(message); } _subject.OnCompleted(); } )); }

public IDisposable Subscribe(IObserver<string> observer) => _subject.Subscribe(observer);

public static FramedMessages From(IObservable<byte> bytes) => new FramedMessages(bytes);}

onCompleted: () =>{ var a = buffer.ToArray(); if (a.Length != 0) { var message = Encoding.UTF8.GetString(buffer.ToArray()); _subject.OnNext(message); } _subject.OnCompleted();}

Exemplo 2: Tratamento inteligente de eventos de UI (JavaScript)

Exemplo 3: Gerenciando fluxo de dados de API externa

var framesGrabbed = Observable.FromEventPattern( h => _capturer.ImageGrabbed += h, h => _capturer.ImageGrabbed -= h ) .Sample(TimeSpan.FromSeconds(1));

// frame to bitmapvar bitmaps = framesGrabbed.Select( args => ((Capture)args.Sender).QueryFrame().Bitmap );

Exemplo 4: Combinando eventos I

var form = this;

var mouseDown = Observable.FromEventPattern<MouseEventHandler, MouseEventArgs>( h => form.MouseDown += h, h => form.MouseDown -= h);

var mouseUp = Observable.FromEventPattern<MouseEventHandler, MouseEventArgs>( h => form.MouseUp += h, h => form.MouseUp -= h);

var mouseMove = Observable.FromEventPattern<MouseEventHandler, MouseEventArgs>( h => form.MouseMove += h, h => form.MouseMove -= h);

var dragging = from down in mouseDown from move in mouseMove.TakeUntil(mouseUp) select new { Start = down.EventArgs.Location, Finish = move.EventArgs.Location };

var subscription = dragging.Subscribe(info =>{ using (Graphics g = form.CreateGraphics()) g.DrawLine(Pens.Red, info.Start, info.Finish);});

Exemplo 5: Reconhecendo sequências

var keyUp = Observable.FromEventPattern<KeyEventHandler, KeyEventArgs>( h => form.KeyUp += h, h => form.KeyUp -= h).Select(key => key.EventArgs.KeyCode);

Func<Keys, IObservable<Keys>> WherePressedIs = (searchedKey) => keyUp.Where(k => k == searchedKey);

Func<Keys, IObservable<Keys>> WherePressedIsNot = (searchedKey) => keyUp.Where(k => k != searchedKey);

var abcPressed = from fst in WherePressedIs(Keys.A) from snd in WherePressedIs(Keys.B).Take(1).TakeUntil(WherePressedIsNot(Keys.B)) from thd in WherePressedIs(Keys.C).Take(1).TakeUntil(WherePressedIsNot(Keys.C)) select new Unit();

Adotando Actor Model

Ele foi definido em 1973 por Carl Hewitt

Define uma abstração para Sistemas Distribuídos e Concorrentes

Foi popularizado na linguagem ERLANG

class CapturerActor : ReceiveActor{ private readonly IActorRef _recognizer;

public CapturerActor(IActorRef recognizer) { _recognizer = recognizer; Waiting(); }

private void Waiting() { Receive<Messages.StartCapturingMessage>(m => { Execute(); Become(Running); }); }

private void Running() { Receive<Messages.StopCapturingMessage>(m => { _handler.Dispose(); _capturer.Dispose(); Become(Stopped); }); }

private void Stopped() { }

private Capture _capturer; private IDisposable _handler;

public void Execute() { _capturer = new Capture(); WriteLine();

// get a frame per second var framesGrabbed = Observable.FromEventPattern( h => _capturer.ImageGrabbed += h, h => _capturer.ImageGrabbed -= h ) .Sample(TimeSpan.FromSeconds(1));

// frame to bitmap var bitmaps = framesGrabbed.Select( args => ((Capture)args.Sender).QueryFrame().Bitmap );

_handler = bitmaps.Subscribe(bitmap => _recognizer.Tell(bitmap));

_capturer.Start(); }}

class CapturerActor : ReceiveActor{ private readonly IActorRef _recognizer;

public CapturerActor(IActorRef recognizer) { _recognizer = recognizer; Waiting(); }

private void Waiting() { Receive<Messages.StartCapturingMessage>(m => { Execute(); Become(Running); }); }

class CapturerActor : ReceiveActor{ private readonly IActorRef _recognizer;

public CapturerActor(IActorRef recognizer) { _recognizer = recognizer; Waiting(); }

private void Waiting() { Receive<Messages.StartCapturingMessage>(m => { Execute(); Become(Running); }); }

private void Running() { Receive<Messages.StopCapturingMessage>(m => { _handler.Dispose(); _capturer.Dispose(); Become(Stopped); }); }

private void Stopped() { }

private Capture _capturer; private IDisposable _handler;

public void Execute() { _capturer = new Capture(); WriteLine();

// get a frame per second var framesGrabbed = Observable.FromEventPattern( h => _capturer.ImageGrabbed += h, h => _capturer.ImageGrabbed -= h ) .Sample(TimeSpan.FromSeconds(1));

// frame to bitmap var bitmaps = framesGrabbed.Select( args => ((Capture)args.Sender).QueryFrame().Bitmap );

_handler = bitmaps.Subscribe(bitmap => _recognizer.Tell(bitmap));

_capturer.Start(); }}

private void Running(){ Receive<Messages.StopCapturingMessage>(m => { _handler.Dispose(); _capturer.Dispose(); Become(Stopped); });}

class CapturerActor : ReceiveActor{ private readonly IActorRef _recognizer;

public CapturerActor(IActorRef recognizer) { _recognizer = recognizer; Waiting(); }

private void Waiting() { Receive<Messages.StartCapturingMessage>(m => { Execute(); Become(Running); }); }

private void Running() { Receive<Messages.StopCapturingMessage>(m => { _handler.Dispose(); _capturer.Dispose(); Become(Stopped); }); }

private void Stopped() { }

private Capture _capturer; private IDisposable _handler;

public void Execute() { _capturer = new Capture(); WriteLine();

// get a frame per second var framesGrabbed = Observable.FromEventPattern( h => _capturer.ImageGrabbed += h, h => _capturer.ImageGrabbed -= h ) .Sample(TimeSpan.FromSeconds(1));

// frame to bitmap var bitmaps = framesGrabbed.Select( args => ((Capture)args.Sender).QueryFrame().Bitmap );

_handler = bitmaps.Subscribe(bitmap => _recognizer.Tell(bitmap));

_capturer.Start(); }}

private Capture _capturer;private IDisposable _handler;

public void Execute(){ // configuring the camera _capturer = new Capture();

// get a frame per second var framesGrabbed = Observable.FromEventPattern( h => _capturer.ImageGrabbed += h, h => _capturer.ImageGrabbed -= h ) .Sample(TimeSpan.FromSeconds(1));

// frame to bitmap var bitmaps = framesGrabbed.Select( args => ((Capture)args.Sender).QueryFrame().Bitmap );

_handler = bitmaps.Subscribe(bitmap => _recognizer.Tell(bitmap));

_capturer.Start();}

_myActorSystem = ActorSystem.Create(“MyActorSystem");

var props = Props.Create(() => new RecognizerActor()) .WithRouter(new RoundRobinPool(10));

var recognizer = _myActorSystem .ActorOf(props, "recognizer");

var capturer = _myActorSystem .ActorOf(Props.Create(() => new CapturerActor(recognizer)), "capturer");

capturer.Tell(Messages.StartCapturing());

elemarjr.com@elemarjrlinkedin.com/in/elemarjr

elemarjr@ravendb.netelemarjr@gmail.com

Mantenha contato!

Programação Reativa e o Actor Model

Elemar Júnior@elemarjr

elemarjr@ravendb.netelemarjr@gmail.com

elemarjr.com

top related