Tamir Dresher
Senior Software Architect
November 2015
Reactiveness All The Way
About Me
• Software architect, consultant and instructor
• Software Engineering Lecturer @ Ruppin Academic Center
• Reactive Extensions in Action (Manning)
@tamir_dresher
tamirdr@codevalue.net
http://www.TamirDresher.com.
Software Architecture is like Pasta
3
By @benorama
4
Social
media
RSS feeds
GPS
Server management
Your System
Being Reactive
5
Responsive
Resilience
React to users
React to failures
http://www.reactivemanifesto.org/
Resiliency
6
You know you have a distributed system when the crash of a
computer you’ve never heard of stops you from getting any
work done.
- Leslie Lamport -
Being Reactive
7
Responsive
Resilience
React to users
React to failures
Being Reactive
8
Responsive
Resilience
Message Driven
React to users
React to failures
React to messages
Being Reactive
9
Responsive
Elastic Resilience
Message Driven
React to users
React to failuresReact to load
React to messages
Being Reactive
10
Responsive
Elastic Resilience
Message Driven
React to users
React to failuresReact to load
React to messages
Reacting to Changes (notifications) with Rx
• Observables
• Observers
• Operators
• www.ReactiveX.io
11
g(x)
f(x)
Rx Example
12
1. At least 4 characters
2. Don’t overflow server (0.5 sec delay)
3. Don’t send the same string again
4. Discard results if another search was requested
Rx Example
13
Rx.Observable.fromEvent($('#input'),'keyup')
.map(e => e.target.value)
.filter(text => text.length > 3)
.throttle(500 /* ms */)
.distinctUntilChanged()
.flatMapLatest(searchWikipedia)
.subscribe(
data => {
/* handle the results */},
error => {
/* handle any errors */});
Observable.FromEventPattern(txtBox,“TextChanged”)
.Select(_ => txtBox.Text);
.Where(txt => txt.Length > 3);
.Throttle(TimeSpan.FromSeconds(0.5))
.DistinctUntilChanged()
.Select(text => SearchAsync(text))
.Switch()
.Subscribe(
results => {
/* handle the results */ },
ex => {
/* handle any errors */ } );
RxJS Rx.NET
Back Pressure
14
3 per sec 1 per sec
http://www.reactive-streams.org/
Publisher Subscriber
demand
• “Push” behavior when consumer is
faster
• “Pull” behavior when producer is
faster
The Actor Model (Hewitt et al. 1973)
15
Alice
Mailbox
Bob
Sally
Mailbox
Mailbox
“the Actor model retained
more of what I thought
were the good features of
the object idea.”
Alan Kay
Object Orientation pioneer
and Smalltalk co-designer
Alice
Parent
Bob
Parent
Sally
Parent
Akka Example
16
class SimpleActor extends Actor {
override def receive: Receive = {
case x =>
println("Received message: " + x)
}
}
object Main extends App {
val system = ActorSystem(“actor-system")
val anActor: ActorRef =
system.actorOf(Props[SimpleActor])
anActor ! "Hello world"
} akka {
actor.deployment {
/simpleActor {
remote = "akka://actor-system@127.0.0.1:3232"
}
}
}
Akka Parental Supervision
17
override val supervisorStrategy =
OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 1 minute) {
case _: ArithmeticException => Resume
case _: NullPointerException => Restart
case _: IllegalArgumentException => Stop
case _: Exception => Escalate
}
1. OneForOneStrategy – affect only the failing child
2. AllForOneStrategy – affects the failing child & it’s siblings
Child
Parent
Child
Summary
18
manning.com/dresher
Discount code:
ctwswarch
http://www.reactivemanifesto.org/
Presenter contact details
t: @tamir_dresher
e: tamirdr@codevalue.net
b: TamirDresher.com
w: www.codevalue.net

Reactiveness All The Way - SW Architecture 2015 Conference

Editor's Notes

  • #2 שלום לכולם, תודה שהצטרפתם אלי ביום חורפי זה
  • #3 שמי תמיר דרשר, אני יועץ בחברת קוד ווליו שמלבד היותה חברת יעוץ במגוון נושאים וטכנולוגיות, היא גם מרכז הפיתוח של כלי הDebugging OzCode ו כמו כן אני מרצה במרכז האקדמי רופין אחד הbuzzwords שאנחנו שומעים יותר ויותר בשנים האחרונות הוא נושא ה Reactiveness של מערכות ושל אפליקציות ובשפות תכנות באופן כללי. גם אותי זה נורא הלהיב, ובפרט הטכנולוגיה שנקראת זה הלהיב אותי כל כך שכתבתי ספר בנושא Reactive Extensions in Action בהוצאת manning קצת Self Promotion לא הזיק אבל בוא נקח רגע צעד אחורה ונסתכל על האבולוציה של הארכיטקטורות שלנו כמו כן אני מרצה במרכז האקדמי רופין אחד הbuzzwords שאנחנו שומעים יותר ויותר בשנים האחרונות הוא נושא ה Reactiveness של מערכות ושל אפליקציות ובשפות תכנות באופן כללי. גם אותי זה נורא הלהיב, ובפרט הטכנולוגיה שנקראת זה הלהיב אותי כל כך שכתבתי ספר בנושא Reactive Extensions in Action בהוצאת manning קצת Self Promotion לא הזיק
  • #4 ארכיטקטורת תוכנה היא נורא דומה לפסטה ואפשר לראות את ההתפתחות שלנו כתעשיה בוסג הפסטה שאנחנו משתמשים בהתחלה כולנו כתבנו ספגטי קוד עם GOTO ואז למדנו שאי אפשר אפילו להבין ולתחזק את מה שאנחנו כתבנו אז עברנו למודל הלזניה והתחלנו לכתוב הכל בשכבות ואז ראינו שלהכין את הלזניה כחתיכה אחת זה לא מספיק טוב, בטח כשיש לנו המון סועדים ועדיף לנו לחלק אותה לחתיכות קטנות יותר מה שיצר את מודל הרביולי – אותם microservices שהם הBUZZWORD שכולם נהנים להגיד איך שלא יהיה, בסופו של דבר יש לנו משתמש שנמצא בקצה אחד שרוצה לקבל שירות, בין אם המשתמש אנושי או מערכת אחרת. והמטרה הסופית שלנו כשעשינו את המערכת זה שהיא תדע להגיב כמו כן אני מרצה במרכז האקדמי רופין אחד הbuzzwords שאנחנו שומעים יותר ויותר בשנים האחרונות הוא נושא ה Reactiveness של מערכות ושל אפליקציות ובשפות תכנות באופן כללי. גם אותי זה נורא הלהיב, ובפרט הטכנולוגיה שנקראת זה הלהיב אותי כל כך שכתבתי ספר בנושא Reactive Extensions in Action בהוצאת manning קצת Self Promotion לא הזיק אבל בוא נקח רגע צעד אחורה ונסתכל על האבולוציה של הארכיטקטורות שלנו
  • #5 המערכת שאתנחנו כותבים היום, יותר מתמיד, צריכות להגיב למסה הולכת וגדלה של אירועים ושל שינויים מרכיבי מסך שמעלים אירועים ועד לחיישנים שמזרימים לנו עדכונים המערכת שלנו צריכה להגיב לכל זה, ולעשות את זה בזמן סביר אחרת המשתמשים שלנו מתעצבנים ועוזבים
  • #6 ההגדרה למה זה מערכות שהם reaectiv מפורט במסמך שנקרא reactive manifesto שפורסם בשנת 2014 ובעצם מסכם סדרה של עקרונות ומאייפינים למערכת שהיא ריאקטיבית הדבר הראשון שאנחנו מגדירים במערכת שהיא ריאקטיבית הוא: responsive הדבר הראשון והחשוב ביותר הוא הצורך שלנו להגיב למשתמשים (בין אם הם אנושיים או שהם מערכות אחרות) המערכת צריכה להגיב בזמן הגיוני לפניות שמתקבלות. אנחנו לא רוצים שהמערכת תעבור סף זמן מסוים לפני שהיא תחזיר תשובה ואני מדבר פה על כל סוג של תשובה. גם להגיד תודה קיבלתי את הפניה זאת תשובה נהדרת זה מה שנקרא להיות רספונסיבי וזה היעד שאנחנו מנסים להגיע אליו.
  • #8   resilient כמובן שעובדת החיים היא שתקלות ושגיאות קורות. זה לא שאנחנו רוצים את זה או מכוונים שזה מה שיקרה אבל אין מה לעשות זה יקרה. ולכן המערכת שלנו צריכה לדעת להגיב לכשלונות (react to failures) להגיב במובן הזה אומר לדעת להתמודד ולהתאושש. כיוון שאחרת לא יהיה לנו responsiveness לדעת להיות resilient לא אומר שאנחנו מנסים לבנות מערכת מושלמת, כזו שאף פעם לא נכשלת. זה רק אומר שאנחנו צריכים לתכנן את המערכת כך שהיא תדע להתמודד עם כשלונות של החלקים שלה. זה אומר למשל לבנות את המערכת בצורה מחולקת כך שכשלון של חלק אחד לא ישפיע על חלק אחר. או לבנות את המערכת כך שחלקים מסוימים ישוכפלו ככה שאם אחד מהם קורס יש אחר שיקח את מקומו. גישה הreactive מקובלת היא לנקוט במבנה של supervision כך שחלק אחד ינטר חלק אחר ויגיב כשהוא נכשל
  • #9   Message driven אם כל המאפיינים שדיברנו עליהם עד עכשיו הם היעדים שאנחנו רוצים מהמערכת אז גישה מונחית הודעות היא ישום של איך אפשר להשיג אותם. כשנעבוד בגישה כזו אנחנו אוטומטית הופכים את התקשורת של לאסינכרונית ולכן באופן מיידי עושים decoupling בין החלקים של המערכת גם במובן של ה-interfaces שהם חושפים וגם מבחינת הזמן הרבה יותר קל לנו לעשות שינויים במבנה המערכת כך שיחידה מסוימת תטפל בהודעה מסוימת או תעשה לה ראוטינג. והרבה יותר קל לשנות את הpriority והסדר של הטיפול בהודעות. כל רכיב במערכת בוחר איך להגיב להודעות בצורה שונה. הודעה מסוימת יכולה להיות הטריגר שלנו לעשות שינוי על כמות הnodes שאנחנו מרימים כדי לטפל בבקשות הבאות. כך שמערכת מגיבה בצורה דינמית ויחד עם האלסטיות אנחנו זוכים למערכת נושמת שמותאמת לצרכים האמיתיים בשטח. ה-decoupling שאנחנו מקבלים בעבודה מבוססת הודעות כך שאין תלות בclient מסוים על מי יטפל בבקשה מאפשר לנו לשלוט בlatency   כל החלקים יחד בסופו של דבר כל המרכיבים מתחברים ביחד. כדי להשיג רספונסיביות אנחנו צריכים שהמערכת תהיה resilience. כדי שנשיג reslieincy אננו רוצים מימד של בקרה על התקשורות ועל הנפילות של החלקים השונים בלי לאבד את הבקשות בדרך. וזה מתקבל על ידי התקשורת שמבוססת על הודעות. כמו כן, ההודעות שמתקבלות מחזקות את היכולת של המערכת להיות רספונסיבית כי קבלת ההודעה לא אומר טיפול בה ולכן תגובה מיידית על קבלת ההודעה עושה את המערכת רספונסיבית. על בסיס ההודעות הללו אנחנו יכולים להשיג אלסטיות שמשנה את מבנה המערכת בסיס כמות ההודעות שיש והמשמעות הספציפית לכל אחת. וכמובן ברגע שהערכת אלסטית אנחנו משיגים resiliency
  • #10     elastic ככל שהזמן חולף ככה המערכת שלנו תיחשף לעומסים שונים אני מקווה בשביל כולכם שהעומס על המערכת שלכם רק יגדל, אבל עומס יכול לגדול בתקופה מסוימת ולרדת בתקופה אחרת כדי להיות responsive ו-resilient המערכת חייבת להיות גמישה. כשהעומס עולה נוסיף Nodes או שנעלה את ה-scale של Nodes אחרים.
  • #11 בסופו של דבר כל המרכיבים מתחברים ביחד. כדי להשיג רספונסיביות אנחנו צריכים שהמערכת תהיה resilience. כדי שנשיג reslieincy אננו רוצים מימד של בקרה על התקשורות ועל הנפילות של החלקים השונים בלי לאבד את הבקשות בדרך. וזה מתקבל על ידי התקשורת שמבוססת על הודעות. כמו כן, ההודעות שמתקבלות מחזקות את היכולת של המערכת להיות רספונסיבית כי קבלת ההודעה לא אומר טיפול בה ולכן תגובה מיידית על קבלת ההודעה עושה את המערכת רספונסיבית. על בסיס ההודעות הללו אנחנו יכולים להשיג אלסטיות שמשנה את מבנה המערכת בסיס כמות ההודעות שיש והמשמעות הספציפית לכל אחת. וכמובן ברגע שהערכת אלסטית אנחנו משיגים resiliency
  • #12 הרכיבים במערכת שלנו צריכים לדעת עכשיו להגיב להודעות שמתקבלות אצל חלק מהרכיבים, למשל הclients שלנו, צריכים להגיב לשינויים שקורים והם לא בהכרח הודעות, למשל תגובה לסנסורים או להקלדות של משתמש – או בקצרה שינוים. זה דורש מאתנו מודל של תגובה לשינויים ואבטסטרקציה על מקור השינויים. בין המקור הוא queue שאנחנו קוראים ממנו הודעות או תיבת טקסט על המסך. אנחנו צריכים מודל שגם יודע להסתכל על אוסף המקורות הללו ועל איך מטפלים במקרים שהם תלויים אחד בשני, או קורים ביחד. בטרמינולוגיה של Rx מקור של הודעות או שינויים נקראה observable והצרכן של השינויים נקרא observer בין שניהם יכולים לבוא אוסף של אופרטורים שמאפשרים להגדיר טרנספורמציות, קומבינציות, פילטורים, אגרגציות ושליטה באורך החיים של הקשר. כך שאפשר לקבל complex event processing היופי בRx שהטרימינלוגיה והסגנון הוא פורטבילי ולא משהו שספציפי רק לשפה אחת – יש לנו Rx לJAVA ל-C++ C# Swift וזה נראה כמעט אותו דבר
  • #14 כך נראת דוגמא בJS וב-C# בשתי הדוגמאות אנחנו הופכים תיבת טקסט לobservable עבור כל שינוי טקסט לוקחים את הערך של הטקסט אם הוא ארוך משלושה תוים ואם עבר זמן של חצי שניה מההקלדה האחרונה ואם ערך הטקסט שונה מהטקסט שכבר קיבלנו עבורו תוצאות בפעם האחרונה אנחנו מבצעים חיפוש על פי הטקסט בצורה אסינכרונית ודואגים שאם הטקסט שונה בזמן שממתינים לתוצאות של החיפודש הקודם אחנו נזרוק את התוצאות שיגיעו ונחכה לתוצאות של הטקסט החדש בסופו של דבר הobserver שלנו מקבל תוצאות אם שגיאות ויכול להציג אותן על המסך או לעבד אותן
  • #15 המודל של הObservable והobserver עובד מאוד טוב אבל אחת הבעיות היא שאם הקצב של הObservable גבוה מהקצב של הobserver אנחנו מגיעים למצב של backpresuure , נוצר לנו עומס שדוחף אחורה, כדי לנסות לתת מענה נוצר הspec של reactive streams שבעצם מוסיף לפרוטוקול בין הobservable ל-observer אפשרות לobserver להודיע לobservable שהוא עמוס ולסמן לו מתי הוא פנוי לקבל עוד נוטיפיקציות Rx לכשעצמו עדיין לא עובד לפי הreactive streams.
  • #16 מודל נוסף שמקיים את הדרישות של ארכיטקטורה שהיא reactive הוא הActor model הוצג ע"י Carl Hewitt ב1973
  • #18 Resume the subordinate, keeping its accumulated internal state Restart the subordinate, clearing out its accumulated internal state Stop the subordinate permanently Escalate the failure, thereby failing itself