ეს მორიგი სტანდარტული პოსტი არ არის ენების / პლატფორმების დაპირისპირებაზე. უამრავი ნეგატიური სტატიის და მოსაზრების მიუხედავად წლებია რაც php-ის ჩემს გულში განსაკუთრებული ადგილი უჭირავს და სულ ვცდილობდი დამედგინა რატომ. ბოლოს სიყვარულის სიბრმავეს დავაბრალე და ტკბილ მოგონებებს, რაც საყვარელ ხალხთან და პროექტებთან მაკავშირებდა, მაგრამ ახლა მე მგონი კიდევ ვიპოვე ერთი დიდი მიზეზი.
მოდი ცოტა შორიდან დავიწყებ.
ერთხელაც, .net რომ ვითარდებოდა ვებში, შემოვიდა asp ვებ ფორმები და პოპულარული გახდა. რამდენჯერ ვცადე შიგნით გარკვევა, რა წიგნები არ წავიკითხე, მაგრამ არ მიმივიდა გული არცერთხელ, თუმცა მიზეზს ვერ ვასახელებდი მაშინ. ეგ მიზეზი იყო თავსმოხვეული ხელოვნურობა. გეუბნებოდა ფრეიმვორკი, რომ მე ვიცი რასაც ვაკეთებ, შენ მარტო ეს ღილაკი დასვი და იმას დააჭირე. მერე მიდიოდა და ზურგს უკან რას აკეთებდა?! 😀 ამხელა სტეიტს დაათრევდა აქეთ იქით რიქვესთებს შორის. მე მგონი პლატფორმა კი არა, ერთი დიდი workaround იყო ვებისთვის.
ვერ ვიტან როცა ფარდის უკან აკეთებენ ყველაფერს. მოხდება შეცდომა და კაცმა არ იცის ვისი და რისი გამოწვეულია სინამდვილეში.
ახლა ჯავა 😀 ჯავა მიყვარს. მაგრამ ვებში ვერ შევეგუე ჯავას. მე მგონი რეალურად ახლა გავიაზრე თუ რატომ ვიყენებთ მისთვის Application სერვერს და არა ვებ სერვერს. უხეში ანალოგია რომ გავაკეთო, წარმოიდგინეთ რომ როგორც დესკტოპისთვის გაუშვებთ რაღაც პროგრამას, ანალოგიურად უშვებთ თქვენს ერთ პროგრამას სერვერზე ყველა მომხმარებლისთვის. ერთს! ყველასთვის! მთელი პარალელიზმი შიგნით არის ფაქტიურად.
Java EE-ში რიქვესთების საპასუხოდ პროგრამისტები ვწერთ სერვლეტ კლასებს, იქ კი instance ცვლადების გაკეთება არ არის კარგი. იცით რატომ? იმიტომ რომ თითო სერვლეტის ერთი ობიექტი გამოიყენება ყველა რიქვესთის საპასუხოდ (მთლად მაგაზე დაყრდნობაც არ შეიძლება, რადგან კონტეინერი აკონტროლებს როდის მოკლას ან ჩაანაცვლოს ის ინსტანსი). სტატიკური რაღაცები, სინგლტონ კლასები – ყველაფერი ჩვეულებრივ არსებობს აპლიკაციაში და shared არის მომხმარებლებს შორის. სპეციალურადაც კი არის ობიექტი – ‘აპლიკაციის კონტექსტი’ რომელიც სერვლეტებს შორის shared მონაცემებს დაატარებს და არაერთ best practice-ში გამოიყენება, თუნდაც რაღაც ობიექტების კეშირებისთვის. ამ ყველაფერს კი სჭირდება სინქრონიზაცია. უნდა იცოდეს პროგრამისტმა რა ბიბლიოთეკები და კლასებია thread-safe, იცოდეს კოდის რა ნაწილი მოხვდება ცალკე ნაკადში და რა ნაწილი იქნება გაზიარებული. მერე შესაბამისად lock-ებით და სინქრონიზაციის სხვადასხვა მექანიზმებით უნდა აკონტროლოს ეს ყველაფერი.
იყო რაღაც ფრეიმვორკები, ახლაც არის. ახლების ნახვის სურვილი აღარც გამჩენია მათ შემდეგ, იმიტომ რომ მე მგონი იმ ვებ ფორმებზე უარესად აფარებდნენ ფარდებს ყველაფერს. მახსოვს Struts რომ მიშრობდა სისხლს. xml-ში აკონფიგურირებდი და მერე ჯადოსნურად უნდა ემუშავა ბევრ რამეს. მაგრამ უმეტეს გაშვებაზე ერთი შეცდომა გამოდიოდა ხოლმე, რაც ჭირივით მეზიზღებოდა 😀 ფაილს ვერ ვპოულობო. ვერ გაიგებდი რა უნდოდა, xml-ში გამოგრჩა წერტილი თუ გადატვირთვა დააკლდა სერვერს. Spring-ზე არც დავიწყებ…
asp.net-ზე როცა იწერება ვებ აპლიკაცია, იქაც ერთი პროგრამა ეშვება. იქაც თუ შექმნით სტატიკურ კლასს, საერთო იქნება და რაღაც საერთო კონტექსტის ობიექტიც ჰქონდათ თუ სწორად მახსოვს. მერე asp MVC ფრეიმვორკი რომ შექმნეს, იქ კარგად ცდილობდნენ ყველა რიქვესთი stateless ყოფილიყო და როცა მომიწია მაგით წერა, ერთი სიამოვნება იყო ჩემთვის რადგან ფაქტიურად ზუსტად ისე ვწერდი როგორც php-ში.
(ცოტა ვურევ ახლა მე ერთმანეთში რაღაც რაღაცებს, მაგრამ ყველაფერზე რომ ვრცლად დავწერო, მთლიანი ბლოგი არ მეყოფა ალბათ).
განა ვაკნინებ ამ პლატფორმებს და ფრეიმვორკებს (ვებ ფორმების გარდა), უამრავი არაადამიანური შრომა არის ჩადებული და მეც წლების მანძილზე გამომიყენებია. მადლობის მეტი რა მეთქმის.
მარტო იმას ვამბობ რომ გაცილებით სასიამოვნო და კომფორტულია ისეთ გარემოში წერა, სადაც ამხელა კომპლექსურობა მოხსნილია და თანაც ისეა მოხსნილი რომ ფარდის უკან გადაძრომა არ გიწევს ხშირად. ჩემთვის ერთ-ერთი ეგეთი გარემოა php.
მეორე გახდა node.js, რომელზეც ქვევით ვიტყვი უფრო დეტალურად.
როცა PHP-ის ვებ სერვერზე ვიყენებთ, უმეტეს შემთხვევაში ისე ვაკონფიგურირებთ რომ ის არ ინახავს არანაირ state-ს. თუ CGI-ის, FastCGI-ის ან Apache-ს Prefork რეჟიმს გამოვიყენებთ, სერვერთან მოსული თითოეული რიქვესთისთვის ახალი პროცესი გაეშვება და მარტო ერთ ნაკადში შესრულდება php-ის კოდი. მაშინაც კი თუ php-ის კომპილირებული ფაილების კეშირებას ვაკეთებთ, სკრიპტის თითოეული ინსტანსი მაინც ცალკე შეიქმნება და ფიზიკური მეხსიერებაც ცალკე გამოეყოფა.
თურმე სახელიც ჰქონია ასეთ მიდგომას – Shared nothing architecture.
მესმის რომ წარმადობის პრობლემა შეექმნება ასე, მაგრამ საშუალო ზომის ვებ აპლიკაციების შემთხვევაში რამდენჯერ მისულხართ მაგ პრობლემამდე?
(ცალკე დეველოპმენტის რეჟიმში კიდევ – არ ვიცი როგორ ახერხებს რომ კოდი სერვერის მხარეს კომპილირდება და მაინც წამიერად მუშაობს. არადა ჯავაზე ან visual studio-ში თუ ვარ, ყველა გაშვებაზე უნდა დაბილდოს-დალინკოს და აშკარად ვამჩნევ მაგას. დაკომპილირებულ ბიბლიოთეკებში ბოდიალი სხვა თემაა კიდევ..)
ჰოდა node.js-ს რაც შეეხება, მანდ საერთოდ მარტო ერთი ნაკადი გვაქვს. მერე უკან, ჩვენს გარეშე კი აქვს რაღაცები გაპარალელებული, მაგრამ პროგრამისტები რასაც ვწერთ, იქ ერთისთვის ვწერთ და სრულიად არ გვანაღვლებს race condition-ები. მაგის მოდელზე ჯობია ცალკე პოსტს დავწერ.
node-ში წერასაც ექნება თავისი ნაკლები და ბევრჯერ წავიმტვრევ ალბათ ცხვირსაც, მაგრამ ნაკადებზე რომ არ ვფიქრობ, ძალიან მომწონს.
ისიც მესმის, რომ ნელ-ნელა გარდაუვალი გახდება წარმადობაზე ფიქრი და წინსვლისთვის მაინც მოგვიწევს ისეთი პროგრამების შექმნა, რომლებიც ბევრი პროცესორისთვის და ბევრი ნაკადისთვის იმუშავებს, მაგრამ რაღაცნაირად იმედი მაქვს რომ იქნება რაღაც იდეები (მაგალითად როგორც node.js ან როგორც nosql ბაზები) და ნაწილობრივ მაინც მოგვაცილებენ shared state-ის თავისტკივილს.
მეტყვით ალბათ, რომ სიზარმაცის და Thread-ების აზრზე არ ყოფნის გამოა ეს ყველაფერი გამოწვეული. მაგის უარყოფას არ დავიწყებ 🙂