“Develop in Pharo, Deploy in Gemstone” with Seaside Johan Brichau
Total Page:16
File Type:pdf, Size:1020Kb
10 Years later “develop in Pharo, deploy in Gemstone” with Seaside Johan Brichau - [email protected] Yesplan ? Web Application (SaaS) to manage an event venue Yesplan ? Web Application (SaaS) to manage an event venue Yesplan ? Web Application (SaaS) to manage an event venue Yesplan ? Web Application (SaaS) to manage an event venue - jQuery - jQuery-UI - KnockoutJs - D3.js - Datatables - Jasper reports - …. Yesplan ? Web Application (SaaS) to manage an event venue - jQuery - jQuery-UI - KnockoutJs - D3.js - Datatables - Jasper reports ReactJs - …. Yesplan ? • Founded by aa. and arts centre • Over 200 customers (in BE, NL, Lux, CH, UK, NO, DK, FI) • Currently 25 employees: • 5 software engineers, 1 dev ops engineer, 1 interaction designer and 1 report engineer • sales, account management, marketing, support, • Emphasis on making an application that not only works, but also is enjoyable to use Yesplan 0.1 (2009) • Yesplan calendar built using Seaside’s “full page rendering” in-place editing info bubbles title • Standard ‘component calls component’ implementation group • A lot of jQuery for animations and ajax updates group visualization • Javascript universe was “big mess” (excluding notable exceptions) • More errors than functionality in most ‘plugins’ • Bad performance and horrible engineering • Pharo + GoodsDB in production Yesplan 1.0 (2010) • Yesplan calendar with incremental ajax updates • A lot of jQuery-based scripts • SVG animations using generated Javascript • Develop in Pharo, deploy in GemStone • Pharo for development • GemStone for deployment • Unit tests + Seaside Component Tests Yesplan 1.0 (2010) • Yesplan calendar with incremental ajax updates • A lot of jQuery-based scripts Magma Goods Goods w/ manual barrier Gemstone • SVG animations using generated Javascript 6 • Develop in Pharo, deploy in GemStone 4,5 • Pharo for development 3 seconds 0,68s 1,5 • GemStone for deployment 0 • Unit tests + Seaside Component Tests 1 commit after one change in 100 000 loaded objects Yesplan 1.x (2010-2013) html span class: 'name'; • Seaside with a lot of Javascript generation passenger: self; with: self visibleresourceUse event name. • Separate Javascript source code files html jQuery this • on: 'click' jQuery event delegation selector: '.name' do: ((JSStream on: 'editEventName(event.target)') asFunction: #(event)) • Parasol html document addLoadScript: • Selenium (Webdriver) testing ((((html jQuery expression: (JSStream on: 'target')) editable type: 'text'; callback: [ :val | nameValue value: val ]; secondCallback: (html jQuery ajax • Targeted at Seaside apps but not limited to callback:[:theCells | theCell value changeEventName: nameValue value]] passengers: ((html jQuery expression: (JSStream on: 'target'))); script: [:s | s<< (theCell value afterNameUpdateScriptOn: s)]); yourself) asFunction: #(target)) assignTo: 'editEventName'). Yesplan 1.x (2010-2013) Yesplan 1.x (2010-2013) Yesplan 1.x (2010-2013) Yesplan 1.x (2010-2013) Yesplan 1.x (2010-2013) Yesplan (2014-2015) • Experiment with Hybrid Web Application • Server-side session: Seaside • Client-side UI: d3js, KnockoutJs, BackboneJs,… Yesplan (2014-2015) • Experiment with Hybrid Web Application • Server-side session: Seaside • Client-side UI: d3js, KnockoutJs, BackboneJs,… Yesplan (2014-2015) • Experiment with Hybrid Web Application • Server-side session: Seaside • Client-side UI: d3js, KnockoutJs, BackboneJs,… Yesplan (today) • Full Hybrid Web Application • Server-side session mgmt: Seaside • Existing UI: server-side Seaside • New UI: client-side ReactJs • Operations • SmalltalkCI (Travis-CI), parallel running test packages • Sentry central error logging (Js + Smalltalk) • Numbers • +200 Gemstone databases • +2000 simultaneous sessions generated Client Server Web components Operations Data objects generated rich client application Client Server Web components REST API Reporting engine Mobile Portal Operations Data objects Seaside-based ReactJs <html> … <body> …. <script> … </script> </body> </html> Seaside-based ReactJs <html> … <body> …. <script> … </script> </body> </html> Develop in Pharo, deploy in Gemstone • Key Tools • Pros • Grease • Seaside in GsDevKit • Metacello • “Transparent” persistency • https://github.com/GsDevKit/ • Licensing model • Gemstone performance, Pharo coolness • Cons • NO ORM • Dialect differences only become larger • Live debugging of production environment • Pharo-specific classes • “Transparent” persistency Yesplan API v1.0.1 - 12 April 2013 profiles[0…n] Cost model Custom data item name : string durationdiscount Discount name : string Resourcegroup costing Resourcebooking costing account : string (or null) notation : string keyword : string group: string alteration : string (or null) purchaseprice : decimal type : string volumediscount rates : integer[2][1…n] alteration : string (or null) cost : decimal (or null) invoice : boolean children[0…n] cost : decimal (or null) resourcecostings[1…n] price : decimal (or null) costmodel cost : string (cost formula) (1 or array) price : decimal (or null) actualprice : decimal (or null) price : string (cost formula) (1 or array) vat: decimal (or null) invoice : boolean costing vat : decimal Custom data group Custom data element actualprice : decimal (or null) accountableto: string Abstract Resourcebooking type : string number : integer value : string|integer|decimal|date|time|datetime| costings[1…n] children[1…n] role : string (or null) resource groups[0…n] resourcebooking | contactbooking (or null) ResourceSetbooking costing event Abstract Resource Event Costings [0…n] resourcetype : string name : string alteration : string (or null) Resourcebookinggroup Resourcebooking customdata Custom data List group : string cost: decimal (or null) actualnumber: integer [opt.] roles : string[0…n] price : decimal (or null) event actualstart: datetime [opt.] Event Resource Booking List description : stringcustomdata netprice : decimal (or null) actualend: datetime [opt.] vat: decimal (or null) external : boolean actualprice : decimal (or null) rented : boolean children[0…n] children[0…n] resource costmodels[0…n] Resource custom data List Singleton Resourcebooking Standard Resourcebooking Resourcesetbooking start : datetime start : datetime actualnumber: integer [opt.] Placeholder end : datetime end : datetime Resource actualstart: datetime actualstart: datetime [opt.] amount : integer actualend: datetime actualend: datetime [opt.] actualnumber: integer [opt.] Location Resource Set resources[0…n] Profile locations[0…n] Resourcebooking custom data List name : string color : color costings[1..n] production (or null) resourcebooking Status name : string profile statustypes : string[0…n] Abstract Event event Event custom data List backgroundcolor : color status name : string customdata textcolor : color starttime : datetime attachments endtime : datetime group (or null) history isproduction : boolean Event History List tasks Abstract Schedule Summary Group Schedule schedules[1…n] ??? entries[0…n] History entry time : datetime schedule Group Schedule Summary Event Schedule Summary user : string Attachment List description : string children[0…n] group group attachments[0…n] Group repeatedevent resourcebookings event Attachment Recurrence Abstract Task startdate : date originalname : string repeatedevents [1…n] Event status : string rule : (recurrence rule) type : string defaultscheduledescription : string name : string comment : string recurrence defaultschedulestarttime : datetime team : string date : date defaultscheduleendtime : datetime (or null) cost : decimal user : string attributes : attributedictionary Event Task List tasks[0…n] due : datetime url : string start : datetime tasks[0…n] assignedby : string assignedto : string description : string schedule event contactbookings Task Task Group Event Schedule Event Contact Booking List duration : duration defaultstartidx : integer defaultstopidx : integer contactsbookings[0…n] event entries[0…n] Contactbooking custom data List Schedule entry Event Contact Booking contactbooking description : string role : string customdata starttime : datetime entries[0…n] contact Contact contact Contact custom data List _type : string comment : string (or null) address : string (or null) customdata contactinfo[0…n] labels : string[0…n] name : string attributes : attributedictionary Link Person Organization jobtitle : string vipcode : string (or null) vat : string (or null) department: string (or null) Legend firstname : string type : string (or null) lastname : string Contactinfo addresslines : string (or null) reference link (retrieve needs separate call/request) type : string zipcode : string (or null) value : string country : string (or null) organization nesting link (entity directly included) city : string (or null) links[0…n] subtype links[0…n] person Develop in Pharo: GT ! Develop in Pharo: GT ! Thank you! Johan Brichau [email protected] [email protected].