Pages

October 15, 2009

A Single Thread that can kill Flash

Scroll down for English translation...

זו רטינה.
אמנם לא חסרת תכלית, אך אם באתם בתקווה למצא פתרון, אני מצטער לאכזב אתכם הפעם.
מאד דרמתי מצידי, אבל אני חושב שזה מן ההכרח להצביע על המלך הנודיסט הוותיק - הרי הוא הת'רד היחיד של פלאש.
העובדה שפלאש יודעת לנהל רק ת'רד אחד בניגוד לסביבות ריצה אחרות (.NET, Java וכיו"ב) תמיד הייתה שם ברקע, אך מעולם לא נתפסה כטיעון מהותי נגד הטכנולוגיה. יש הטוענים שאם אתה מתכנת לפלאש פלייר ומצאת עצמך מנסה לנהל ת'רדים, אתה כנראה עושה משהו לא נכון. הוסיפו על כך את העובדה שבכדי לנהל ת'רדים, ה-VM של פלאש אמור לגדול בנפח, וקיבלתם את השיקול העסקי של אדובה לא לגעת בבייבי שלהם.
ברם, RIA, ומעבר לכך - AIR.

מה הבעיה ש'ך?
קחו את התרחיש הבא, בו אפליקציה כלשהי אמורה להשתמש ביכולות גישה ל- File System, ולעשות איזו איטרציה מסויימת על קבצי מערכת, משהו סטייל "ספר לי מה יש שם". תרחיש שיכול להיות בן-בית אהוב באפליקציות AIR, למשל, לא? עכשיו, בכדי שהלקוח שלנו יהיה מרוצה, אנחנו רוצים גם לתת לו חווית משתמש טובה (כי אנחנו מאמינים שאפליקצייה טובה לא נגמרת בארכיטקטורה פונקציונאלית), שתעזור לו להבין שמשהו קורה. progress bar נשמע כמו רעיון מבטיח.
אתם כבר מזהים את הבעיתיות? הרי יש לנו לולאה רקורסיבית שלא עושה הרבה בתוכה, אבל עדיין יכולה לרוץ פוטנציאלית פעמים רבות, מה שייתקע את הת'רד היחיד של פלאש, ושיגרום לכך שדבר, אבל דבר(!) לא יזוז על המסך והפלייר יתקע כמו אוטוביינקי בקסטל. אנחנו נחלוק מזל גדול אם ה- Progress Bar יעלה בכלל לתצוגה.

מכעיס?
עכשיו תגידו לי, האם הת'רד הגלמוד הזה הוא משהו שאדובה צריכים לשים בראש סדר העדיפויות שלהם במירוץ אל עבר כיבוש פסגת האפליקציות רשת העשירות ואפליקציות הדסקטופ? ברור שכן!
זה נחמד מאד שהפלייר הוא קטן, וזה מאד התאים לאתרים ברשת, אבל הזמנים משתנים ואי אפשר לקפוא על השמרים עם הטיעון של "הפלייר שלנו קטן", בייחוד שהמתחרים תומכים גם תומכים בת'רדים מרובים.
אדובי סמכו ועדיין סומכים על קהילת המפתחים האוונג'ליסטית שלהם, שעמלה ימים כלילות במציאת workarounds לכל מיני הגבלות של הפלייר (עברית, מישהו?), אבל הפתרונות לת'רדים מרובים שלא מוטמעים בסביבת הריצה של פלאש הם מסורבלים, יקרים ובכנות? לא אמורים להיות משהו שאנחנו אמורים לפתח.

טוב נו, מה אפשר לעשות?
בשיטוטי לא נתקלתי עדיין בהתייחסות לעניין מצד אדובי בכל המדובר ב- roadmaps לעתיד הפלייר. אני גם לא הייתי שם יהווי על העניין. אתם יודעים. אישית, אני עדיין מחכה לתמיכה ב- Timezones שהובטחה בפלייר 10.
הפתרונות המוצעים בד"כ מדברים על לולאות פשוטות ולא רקורסיביות. איזה מין תמימות המבקשת לפרק לולאות פשוטות לחלקים קטנים יותר ולהריץ אותם בהתחשב בברינדור הפריימים. דוגמה לכך תוכלו למצא בפוסט מצויין של אלכס הרואיי (חובה לקרא את התגובות).

Pixel Bender
נחפש עוד קצת ונמצא את פתרון ה- Pixel Bender. בקצרה, Pixel Bender נועד ליצור אפקטיים חזותיים כמו פילטרים וכדומה על bitmaps, וקטורים ועוד. ת'כלס? אופרציות מתמטיות שמעבדות ביטים, ורצות על ת'רד נפרד. רגע, רגע, אז זה בדיוק מה שאנחנו צריכים לא? יש לנו ת'רד נפרד ועליו נריץ את מה שאנחנו רוצים, לא? ובכן התשובה היא לא. אפשר להריץ שם חישובים מתמטיים אבל לא לולאות. מה שגם, צריך לבנות עבור פעולות מיוחדות קרנלים (כן, Kernels, זוכרים מלינוקס? איזה כיף הא?... בואו נחולל קרנלים!), אז הפתרון הזה נחמד ויפה למניפולציות גראפיות או סאונדיות, כל עוד אין לולאות בעניין. לא טוב לנו. אתם יכולים לקרא על זה פה.

HTML
הלאה, כי אנחנו לא ילדות, ואני מנסה לפתור את העניין עם HTML. עובדה מעניינת אחת היא שאם תטמיעו HTML באפליקציית AIR שלכם, ותקראו לפונקציית JS שתרים Alert, אתם תופתעו לגלות שהת'רד היחיד של פלאש לא משחק שם תפקיד (מן הסתם) וה- Alert עולה כמו נינג'ה. מה שכן, אנחנו לא ממש מעוניינים ב-Alert. אנו רוצים משהו יותר בכיוון של חלון חדש שנפתח, עם פלאש פלייר אחר בתוכו, שיפעל בת'רד הבודד שלו. אתם יודעים מה? עזבו פלאש, אני מארגן progress bar שהוא AJAX נטו בפנים, יותר טוב מזה? אין.
כינים.
בשביל שה-HTML הנחמד שלנו ירונדר הפלייר צריך (ניחשתם נכון) לרנדר אותו, אבל הוא תפוס על הפעולה הרקורסיבית שלו, ושום דבר לא יעזור, ה-HTML לא מראה דבר וחצי דבר.

עוד פתרונות?
אין לי. לכן אני פה, כועס ורוטן. יש לכם? אשמח לשמוע...

סיכום
ישר ולעניין, יש טכנולוגיות מתחרות שתומכות בת'רדים מרובים. עד כאן יש? אחלא.
אם אדובי מעוניינים לשמור על היתרון היחסי שלהם בעולם ה- RIA ובעיקר באיזור ה- Desktop Applications, אני מציע בצניעות שייקחו את עניין הת'רד הבודד של פלאש לתשומת ליבם ובזריז, כי מיקרוסופט לא מחבקת עצים בזמן שהם משתעשעים בכנסי MAX.




This is a mutter
Not completely useless, but if you came here in search for a solution I'm sorry to disappoint you this time.
It's very dramatic of me, but I think it's high time to point out the so obvious fact that Flash has only one thread.
The fact that Flash can run on a single thread only, as opposed to other running environments (.NET, Java etc.), was always on the backgrounds but never was conceived as a major argument against the technology. Some might claim, that when you find yourself in need of multiple threads when developing for Flash, you're probably doing something wrong. Add that fact that in order to manage threads, the Flash player VM needs to grow in volume, and you get the business consideration for Adobe to not touch their little baby.
But then comes RIA and to top it off - AIR.

What's your problem?
Take the next scenario, where there is an application that supposed to use the file system API, and do some kind of an iteration over files. Something like "tell me what's going on in that directory". A scenario that can be a native resident in any AIR application.
Now, for our customer to be happy, we also want to give her a nice UX (cause we truly believe that an application does not end in a mere functional architecture) that will help her understand that some process is running. A Progress Bar sounds like a great idea.
Can you smell the rotten egg already? We have a recursive loop that doesn’t do much inside, but still can potentially run many times, what will eventually stuck Flash single thread and cause that nothing will be renderered on the screen. The player will be jammed and we will be considered lucky if our progress bar will be added to the stage (not to mention, show the progress).

Does it make you mad?
Now you tell me, does this lonely thread is something that Adobe needs to put high at their priority list when racing to conquer the RIA and Desktop Applications realm? Hell yeah.
It's very nice that the player is small, and it goes well with poor Web-Sites, but times are changing and you cannot be stagnated with the argument that "our player is small", especially when the competitors are supporting multi-threading.
Adobe has leaned and still leaning on the evangelist developers community, that works day and night in finding workarounds to many player limitations (RTL someone?), but the solutions to multi-threading support are awkward, expensive and to be honest? Not supposed to be something that we should develop.

Ok then, what can be done?
Roaming the web, I didn't find any reference to the issue from Adobe where it comes to Roadmaps for the future of Flash player. I wouldn't put my money there either. I'm still waiting for the Time zone support promised for Flash player 10.
The solutions suggested usually speak about simple loops and not recursive ones. A naïve approach to divide these loops into smaller routines and run them while considering the frame rate. A sample of that you would find in an excellent post by Alex Harui (reading the comments is a must).

Pixel Bender
If we look a little more we would find the Pixel Bender solution. In short, the Pixel Bender purpose is to create a dynamic visual effects like filters and such, on bitmaps and vector graphics. In a nut shell? Mathematical operations on bits that run on a different thread than the one used by the Flash player.
Hold on! This is exactly what we need, isn't it? Well, the answer is no. you can run mathematical calculations but not loops, and you also need to generate Kernels (yeah, remember that Linux fun?), so this solution is nice for graphic or sound manipulations, but as long as there no support for loops it doesn't really help us. You can read about it here.

HTML
Going on, cause we're not giving up that easily, I try to solve the issue with embedded HTML. One interesting fact is that if you embed HTML into your AIR app, and call a JS function that pops up an Alert, you will find out that Flash single thread doesn't get in the way and the alert goes up when asked, but I want something nicer, like a window. You know what? I don't even need Flash inside that window, I did it all in pure AJAX. Does it get any better than this?
Nothing.
In order to render HTML, the player needs to render the HTML container, but it is caught up in it's loop so nothing happens.

More solutions?
I have none. This is why I'm here… complaining. If you have some, I will be sure happy to hear them.

In conclusion
Straight and to the point, there are other technologies that do support multi-threading.
If Adobe wishes to keep their relative advantage over the competitors, in the RIA section and mostly in the Desktop Applications, I humbly suggest that they will take the matter of multi-threading into consideration, and fast, cause Microsoft ain't gonna wait until the next MAX convention.