ארכיון חודשי: מאי 2013

מה נדרש בשביל אתר ?

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

זה גם לי להיזכר בפעם הראשונה שנגעתי בעולם הווב.אז יצרתי אתר אינטרנט וזה היה ב1997. בתקופה זו, התכנות היה בתוך html, כולל ה עיצוב. ב1999, נכנס html4 שהתחיל לעשות קצת סדר בדברים, וגם css1 מתישהו והפריד חלק מהעיצוב (אם כי בוצע בעיקר בתוך ה html).

ב2005 כתבתי את ספריית ה Javascript הראשונה שלי עבור חברה שעבדתי, שידעה גם לטפל ב AJAX. וב2006 כתבתי ספרייה ברשיון MIT כהוכחת יכולת שעושה הרבה יותר מזה, כולל טיפול באירועים, וכיום ספריות כדוגמת jQuery עובדות בגישה שונה, לפתור את אותן הבעיות שאני טיפלתי בהן, אבל בניסיון לספק את מה שאני ניסיתי (ללא קשר אלי מן הסתם).
כל זה כמובן נחמד, אבל לא קשור לנושא.

כל מי שמפתח כיום תוכנות ברשת האינטרנט באמצעות "אתר", אינו מתכנת רק html. למעשה html זה החלק הקל והפשוט ביותר שיש לתכנות הווב להציע.

החלק המסובך יותר הוא עבודה עם המון כלים וטכנולוגיות מסביב. כולל ניהול שרתים, פריסה אוטומטית, יצירת cgi, הכרה של המון צורות תקשות ופרוטוקלי התחברות ועוד.

למעשה כאשר מדברים כיום על Javascript, מדברים על מטריה אחת להמון טכנולוגיות. למשל בתוכה כיום יש טכנולוגיה בשם web sockets אשר דורשת צד שרת.
ויש גם Javascript בצד שרת כדוגמת node.js. יש גם המון ספריות בשפה אשר נועדו להקל על העבודה, ולנסות ולהתמקד במימוש של דברים.

אנשים נדרשים לדעת להתמודד עם המון מידע ויכולות מורכבות. לדעת לטעון קבצים בהתאם לצורך (amd), לשנות התנהגות ברירת מחדל, לקבוע בכלל מה זו התנהגות ברירת מחדל, להתמודד עם quirks של מספר יצרנים, להבין איך צד השרת עובד, כיצד להתמודד עם פעולות ארוכות מול קצרות, הכרה של המון פרוטוקולים ושיטות שכל הזמן משתנות, מתווספות או יורדות לגמרי, הכירות עם סוגי מסדי נתונים שונים, כולל בצד הclient ועוד הרבה מאוד דברים שדורשים פוסט נפרד רק בשביל להזכיר אותם כאן.

כל אלו, בסופו של דבר דורשים ממך הכירות מאוד מעמיקה עם המון טכנולוגיות, שפות תכנות ופרדיגמות חשיבה שונות בזמן הפיתוח, עבור כל פרוייקט ופרוייקט שאתה מבצע.

למעשה כאשר מדברים כיום על אתר אינטרנט רציני, עומדים מאחוריו כל כך הרבה דברים, שזה מפליא שזה בכלל עובד, ולרוב עוד עובד טוב.

אז מה נדרש בשביל ליצור אתר ? מתכנתים טובים ואיכותיים שמסוגלים להתמודד עם המון אתגרים רציניים, אשר לרוב אינם זוכים לכזו הערכה ממי שאינו מכיר את העולם.

אז האם מי שאינו מסוגל להיות מפתח ווב טוב כיום, בעצם נחשב לאיש מקצוע ומתכנת פחות טוב ?

גימגום השיחה בטלפון

בפוסט זה אני מנסה לתת מענה פחות טכני עבור משהו שהרבה נתקלים בו, ואנסה להסביר אותו בצורה פשוטה וברורה.

כל מי שעובד עם תקשורת טלפוניה דיגיטלית, חווה מידי פעם גמגום במהלך שיחה כזו או אחרת.

לגמגום "הזה" יש שם מקצועי – Jitter. הגמגום הזה נובע מכך שאין המשכיות ברורה בין צליל אחד לשני כפי שהוא אמור להישמע לאוזן האנושית. כלומר הזמנים בין צליל לצליל יכולים להשתנות. פעם לוקח לצליל להגיע מספר מילי שניות בודדות, ופעם לאחר מכן לוקח כשניה בודדת. מה שיוצר מצב בו השיחה נשמעת מגומגמת, קטועה וכיוצא בזה.

על מנת לנסות לפתור את הבעיה, יוצרים סוג של delay מסויים על כמות צלילים הנכנסים אלינו, ומאגדים אותם בייחד ואז שולחים אותם כחבילת קול בודדת לשמיעת האנשים. פעולה שכזו נקראת Jitter Buffer.

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

כאשר אנשים מנסים לבדוק את הטלפונים הסלולריים שלהם באותו החדר בו מתקשר עוד אדם, שומעים לרוב סוג של השהייה בשיחה וזה בין היתר גם בגלל ההתמודדות של ה Jitter בכל צד של השיחה, כולל כל הרכיבים באמצע שכיולו לשם כך. כלומר, הטלפון הסלולרי שלכם כבר עושה את זה, ולרוב גם המרכזיה הדיגיטלית שלכם במשרד עושה זאת. כאשר רחוקים אחד מהשני, זה כמעט בכלל לא מורגש, אך כאשר נמצאים באותו החדר, מרגישים זאת בצורה מאוד ברורה.

ניוד צרות

אז אתם יכולים לנייד את מספר הטלפון שלכם 20 פעם ביום תודות למשרד התקשורת. אממה, עם הניוד באו הצרות.

כיום אין קשר בין מספר חד חד ערכי כדוגמת קידומת, לספק טלפון. על מנת להתמודד עם הבעיה, כל ספק טלפוניה הקים לעצמו מערך מסדי נתונים, במקום להקים מערך אחד לכולם, אשר תפקיד מסדי הנתונים הוא לקבל את המספר שחויג, לבדוק לאן הוא שייך ולפנות לאותו ספק עם המספר הלאה.

אבל יש כמה בעיות עם זה. למשל לא כל מסדי הנתונים מעודכנים כמו שצריך, לפעמים יש מידע שלא מגיע מספק אחד לספק שני, או מגיע באיחור של מספר שעות (אפילו יום או יומיים).

לפעמים מרכזייה מסויימת של ספק אחד שאתם מגיעים אליה מקבלת עותק ישן של המידע, בעוד שמרכזייה אחרת של אותו ספק מקבלת את העותק העדכני, והרשימה של הבעיות עם מסדי הנתונים עוד ממשיכה.

בנוסף לכך, אם זה לא הספיק, הסטטוסים שהתחלנו לקבל על שיחות, מאוד בעייתיות. למשל קורה לי שעל המספר טלפון האישי שלי (אשר נמצא ברשותי  מ2003 בערך), כבר ראיתי כי אני מקבל עליו במרכזיה שטיפלתי כאילו המספק איננו מחובר, רק בשביל לגלות כי היתה בעיה נקודתית אצל ספק סלולרי, שלקח שעה לפתור.

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

יותר מזה אם תעשו בדקה אחת 10 חיוגים לאותו מספר, קורה מצב בו תקבלו 10 סטטוסים שונים על אותו מספר (בהנחה כאמור שהוא מחובר ומסוגל לקבל אותם).

על כל בעיות הניוד, נוספו גם ספקים חדשים, אשר רוכבים על ציוד של חברות קיימות. חברה כדוגמת גולן טלקום, בנוסף גם פורסת אנטנות וציוד משלה, וכעמט כל יום יש תקלה כזו או אחרת שם. חלקם אפילו תקלה ארצית לפרק זמן של מספר שעות.

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

אז מצטער לאחר שנה להרוס לכם את השמחה, אבל המפכה הזו היא בעיקר כאב ראש טכני, אשר פוגע גם במשתמשים הרגילים, ולא, אי אפשר באמת להתנייד 20 פעם ביום. אפילו פעם אחת בשנה היא לפעמים בעייתית בראש ובראשונה עבורכם.

My first ruby framework part 1

I'ved tested many static web page generators, and I found a very horrifying conclusion: They are either too big and overwhelming, or they are very small, compact, and written mostly for generating static blogs.

I'ved started to invest a day with a friend static generator, that he wrote for his blog, and even opened 11 bug reports for it, however, the generator he created is also very blog specific solution, and I want to create static web site, not a blog. The difference is in the way routing works, and the whole stat of mind when using such thing. And if I wish to make his generator do what I'm looking for, it will require from me a lot of work.

So, I'ved started yet another static web site generator (more like a framework for it imho 🙂 ), after I'ved tried not to go there in any possible way.

At the first day I'ved started planning how the skeleton of the static content will be, and started looking for libraries that can convert markup languages (markdown, reStracturedText etc…) to html, and I've chosen something that is written in Haskell, with a lot of power named Pandoc. It even has a Ruby wrapper for it, that I'm using for the project. So I jumped to the water of reinventing the wheel and creating yet another generator.

In the beginning, of writing my code, I'ved encountered several problems that needed to be solved. For example: How do I execute my executable without installing it as a Gem ? In default behaviour, if it's not installed, then Ruby does not know how to locate the files. But at the end I found an interesting solution for it:

$BASE_PATH = File.expand_path(File.dirname(__FILE__) + '/..')

I found additional problems to be solved. For example I needed to make Bundler find the Gemfile, but the executable is not part of the Gemfile path. After a lot of research and grep in the source code of Bundler, I found the answer:
It uses an environment variable named BUNDLER_GEMFILE, and it is needed to be set to the Gemfile path like so:

require 'bundler'
ENV["BUNDLE_GEMFILE"] = $BASE_PATH + '/Gemfile'
Bundler.require(:default)

Another problem that I found was in the way of parsing the cli parameters.
Ruby has it's own default library for it, but it was not built for what I was looking for.
So later on, I found a library named slop that is very nice, and works well, but not 100% of what I was looking for.
When I read the Bundler source code, I found Thor, and finally found the proper parser for me, but I will not use it in this version.

I find it very interesting how writing something like a framework takes different way of thinking then normal program.

It is very important to emphasize that at the time of writing this post, my code is still not ready, and many basic things are not implemented, and the core is constantly rewritten. But the next post will be about v0.1 that is ready 🙂

ליצור פריימוורק ברובי חלק ראשון

עברתי על הרבה מאוד מחוללי אתרים סטטיים, והגעתי להבנה מאוד רעה: או שהם מפלצתיים מסובכים ומסורבלים מאוד, או שהם פשוטים מאוד אבל נכתבו למטרה מאוד ספציפית, לרוב עבור יצירת בלוג.

השקעתי יום וקצת למשל במה שמאיר כתב עבור הבלוג שלו, ואפילו פתחתי לו 11 באגים, שמספר מהם כבר סודרו (המשך כך מאיר), אבל גם המחולל שלו, שמאוד פשוט (מקדימה, לא מאחורה), בנוי להיות בלוג. אבל אני רוצה להיות אתר עם דפים סטטיים, ולא בלוג. זה אומר כי כל הטיפול ב routing ובגישה בכללותה של איך עובדים עם התוכן מושפעת מזה. ובשביל לגרום למחולל שלו להיות כללי יותר נדרש יותר עבודה.

אז בצער רב וביגון קודר, התחלתי ליצור עוד מחולל סטטי משל עצמי. משהו שמאוד לא רציתי לעשות. השקעתי כמעט שבוע במחקר רק בשביל להימנע מזה. ובכל זאת 😦

ביום הראשון להתחלתי, תכננתי איך השלד נראה, כתבתי ספסיפיקציה (עדיין לא שלמה) איך התוכן יראה לפני היצירה שלו כדף html, מצאתי המון ספריות שיודעות להמיר markup זה או אחר לhtml ובחרתי דווקא משהו שכתוב ב haskell (שימוש ראשון שלי למשהו שכתוב בשפה) אבל עם המון פוטנציאל וכוח שנקרא Pandoc . יש לו אפילו wrapper ברובי שאני משתמש לפרוייקט, וקפצתי למים העכורים של משהו שכל כך שנוא עלי – להמציא את הגלגל מחדש בפעם המליארד.

ואז נתקלתי במספר בעיות. איך אני מריץ קוד רובי שצריך להשתמש בספרייה שתגיע בתור gem ? בברירת מחדל, אם זה לא מותקן, אז אין לי דרך להגיד לרובי את המיקום של הקבצים. בסוף מצאתי לזה פתרון די פשוט, אבל לקח זמן להגיע אליו:

$BASE_PATH = File.expand_path(File.dirname(__FILE__) + '/..')

לאחר מכן, נתקלתי בעוד בעיות.
למשל היתה בעיה איך אני גורם לקובץ הריצה למצוא את Gemfile כאשר אני לא רץ בספרייה שהוא נמצא בה.
חיפוש וחפירה בהרבה מאוד קוד, גילה שיש רק דרך אחת לעשות זאת, וזה להשתמש ב environment variable של bundler בשם BUNDLE_GEMFILE :

require 'bundler'
ENV["BUNDLE_GEMFILE"] = $BASE_PATH + '/Gemfile'
Bundler.require(:default)

ועכשיו הוא יכול לעבוד כמו שצריך.

בעיה נוספת שנתקלתי בה, היא ניתוח של הפרמטרים לcli שרציתי.
יש לרובי ספרייה ממש נחמדה שמגיעה כחלק ממנו, אבל היא לא בנויה למה שחיפשתי.
אז חיפשתי משהו אחר, ומצאתי את slop. די נחמד. עדיין עובד קשה קצת, אבל פחות ממה שמגיע עם רובי עבור הצורך שלי.
יותר מאוחר גיליתי ספרייה טובה יותר, אבל רק בגרסה הבאה של מה שאני יוצר אעבור אליו, וזה נקרא Thor. היא נבנתה באמת למה שאני צריך, אבל גיליתי אותה בשלב שהחלטתי כבר להתמקד בעיקר קודם כל.

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

חשוב לי עוד להדגיש כי נכון לכתיבת הפוסט, עדיין המערכת לא בנויה לשימוש נרחב, הקרנל אפילו עדיין לא מומש, ובנוסף היא ועוברת המון שינויים כולל בתכנון שלה, ובדרכי העבודה, כך שעד שלא אפרסם כאן שזה מוכן, תהיו צריכים לחכות בסבלנות.

הפצת לינוקס מול תוכנה

לפני מספר חודשים היה ויכוח גדול בwhatsup בו הועלו הרבה נושאים מדוע גישה מסויימת היא לא נכונה והגישה הנכונה היא כי יש לחשוב לפי הפצת לינוקס, ולא לפי צרכי התוכנה שלך.

אבל יש מספר בעיות שאנשי תוכנה אשר אינם מתמקדים בהפצה זו או אחרת נתקלו בהם, ופתאום אנו רואים כי נכתבים מערכות ניהול לשפות תכנות. ואם זה לא אומר דרשני, אז כמעט כל סביבת ניהול שפת תכנות מודרנית כיום מנסה לספק לבעיות שהפצות הלינוקס הולידו מענה.

אז מה הן הבעיות ? הנה רשימה חלקית:

  • עדכון דחוף מידי של ספריות שזקוקים להם
  • חוסר עדכון של ספריות שזקוקים להם
  • תיקוני באגים של הפצה, השוברים אפליקציה
  • צורך בלשמור גרסאות כלים מסויימת
  • שימוש במספר גרסאות שונות של ספריות לביצוע עבודה (למשל שרת המחזיק מספר אתרים)
  • שוני בין הפצות שונות, קצב ההתקדמות שלהם, ניהול הקבצים בתוכם וכיוב' …
  • שינוי ABI/API בספריות שונות תלוי בגרסאות הספריה. להמשיך לקרוא

דרושה חשיבה חדשה לחקיקת מזיקים

אחת מהבעיות הגדולות שרובינו חווים, היא ספאם אלקטרוני.

ישנו "חוק הספאם", אך הוא לוקה בחסר, היות והוא דורש ממני בכל זאת לעבוד קשה ולהתמודד עם התופעה באופן פרטני. כלומר כל מטריד צריך לקבל ממני פעולה שתסיר אותי ממנו, ובמידה וזה לא עוזר להגיש תביעה משפטית.

אבל אז מגיעים גופים למשל כמו קבר רחל, ומתחילים להספים בצורה שהיא חסרת גבולות,
אני חושב כי הפתרון לכך יכול להיות די פשוט – רשימה כחלק ממשרד ממשלתי (למשל משרד התקשורת) בה מספרי טלפון ודוא"ל יכולים להרשם בצורה שאומרת כי אסור לפנות אליהם בהצעות שיווקיות, תרומות ועוד (לפי אפשרויות שונות). במידה ותהיה פניה שכזו, העונש יהיה תשלום גבוה של מינימום כ10,000 ש"ח ועד 30,000 ש"ח (אם היתה יותר מפניה אחת) ללא הוכחת נזק כלשהו, או דרישה ממקבל הפניה להסיר עצמו קודם לכן.

ויותר מזה, גוף אשר מטריד באופן סדרתי אחרים, יועמד לדין על ידי משרד התקשורת, ויקבל קנסות יותר גבוהים אשר יכנסו כהוצאות לאכיפה הזו, וכן עם אפשרות לשלם פיצויים לנפגעים השונים, גם אם הם לא הגישו תביעה בנושא.

כך בראש ובראשונה יהיה כלכלי יותר לתבוע את המטרידים, ומצד שני למנוע הטרדות מאלו שלא רוצים לקבל מהם הטרדה.

כל מה שצריך זה לנסח בצורה ברורה את הרשימה של מה רוצים למנוע.