SlideShare a Scribd company logo
Caching and
    Synchronization in Flex

    Zachary Pinter
    Senior Developer
    EffectiveUI
    360Flex




1
The Problem



       How do we keep live (changing) server data
        synchronized across multiple views and
                   multiple users?




2
The Approach




           Fetch entities only once and only
                    when needed.




3
The Approach




          One definitive instance of a server-
                      side entity.




4
The Approach



          Update all relevant views when the
          server sends notice that an entity
                     has changed.




5
The Approach




               Server-side agnostic.




6
What’s the strategy?




           Store all fetched entities in a single
                    cache (Dictionary).




7
What’s the strategy?




              Bind the views to the cache.




8
What about memory use?
    public class WeakReference                 Allows cache values to be
    {                                          garbage-collected if they’re not
                                               being referenced anywhere else.
        private var dic:Dictionary;

        public function WeakReference(obj:*)
        {
           dic = new Dictionary(true); Text
           dic[obj] = 1;
        }

        public function getValue():* {
           for (var item:* in dic) {
              return item;
           }
           return null;
        }

    }


9
The Cache
     How do we add an entity to the cache?


     public class EntityCache
     {
        public function updateEntity(entity:BaseVO, ...):BaseVO
        {
           //...
        }
     }




10
Recurse through properties
     Adding a user to the cache also adds its address.
     UserVO
      id: 1
      firstname: “Zachary”
      lastname: “Pinter”                                 EntityCache
      address:                                            1: UserVO
        AddressVO                                         2: AddressVO
         id: 2
         line1: “4444 W 44th Ave”
         city: “Denver”
         state: “CO”




11
Recurse through properties
     Arrays behave the same way
     UserVO
      id: 1
      firstname: “Zachary”
      lastname: “Pinter”
      addresses: [                  EntityCache
        AddressVO
                                     1: UserVO
         id: 2
         label: “home”               2: AddressVO
         line1: “4444 W 44th Ave”    3: AddressVO
         city: “Denver”
         state: “CO”
       AddressVO
         id: 3
         label: “work”
         line1: “5555 W 55th Ave”
         city: “Denver”
         state: “CO”]
12
Finding an object’s properties
     Spring Actionscript (formally Prana)
     http://www.pranaframework.org/

     var type:Type = Type.forName(classname);

     for each (var accessor:Accessor in type.accessors) {
        if (accessor.isStatic == false && accessor.access.name == quot;readwritequot;) {
           result.push(accessor.name);
        }
     }
     return result;




13
Finding an object’s properties
     Source generator



     public class UserVO extends BaseVO {
        public var username : String;
        public var firstname : String;
        public var lastname : String;
        public var address : AddressVO;

         override public function getProperties():Array {
            return super.getProperties().concat(quot;usernamequot;,quot;firstnamequot;,quot;lastnamequot;,quot;addressquot;);
         }
     }




14
Updating the cache
     What if the entity is already in the cache?

         EntityCache                           EntityCache.updateEntity(
          1: UserVO(instance A)                  UserVO(instance B)
              id: 1                               id: 1
              firstname: “Robert”                  firstname: “Bob”
              lastname: “Smith”                   lastname: “Smith”
                                               )

                                                         Copy the properties from
                                                         instance B into instance A
                            EntityCache
                                                         Leave instance A in the
                             1: UserVO(instance A)
                                                         cache
                                 id: 1
                                 firstname: “Bob”         Discard instance B
                                 lastname: “Smith”

15
Updating the cache
     What about arrays?
     EntityCache
      UserVO
       id: 1
       firstname: “Zachary”
       lastname: “Pinter”            EntityCache.updateEntity(
       addresses: [                    AddressVO(instance B)
         AddressVO(instance A)
                                        id: 2
          id: 2
          label: “home”                 label: “home”
          line1: “4444 W 44th Ave”      line1: “3333 W 33rd Ave”
          city: “Denver”                city: “Denver”
          state: “CO”                   state: “CO”
        AddressVO                    )
          id: 3
          label: “work”
          line1: “5555 W 55th Ave”
          city: “Denver”
          state: “CO”]
16
Updating the cache
     What about arrays?

     UserVO
      id: 1                         Since we update the existing instance,
      firstname: “Zachary”           all references to it will see the update.
      lastname: “Pinter”
      addresses: [
        AddressVO(instance A)
         id: 2
         label: “home”
         line1: “3333 W 33rd Ave”
         city: “Denver”
         state: “CO”
       AddressVO
         id: 3
         label: “work”
         line1: “5555 W 55th Ave”
         city: “Denver”
         state: “CO”]
17
Updating the Cache
     The flip side
                                             UserVO
     EntityCache                              id: 5
      AddressVO(instance A)                   firstname: “Zachary”
                                              lastname: “Pinter”
        id: 2
                                              addresses: [
        label: “home”                           AddressVO(instance B)
        line1: “5555 W 55th Ave”                 id: 2
        city: “Denver”                           label: “home”
        state: “CO”                              line1: “6666 W 66th Ave”
                                                 city: “Denver”
                                                 state: “CO”
     Your cache already has an
                                               AddressVO
     AddressVO with id 2 in it, and you
                                                 id: 3
     add a new UserVO to the cache that
                                                 label: “work”
     references an updated instance of the
                                                 line1: “5555 W 55th Ave”
     AddressVO
                                                 city: “Denver”
                                                 state: “CO”]

18
Updating the Cache

                                         UserVO
     EntityCache                          id: 5
      AddressVO(instance A)               firstname: “Zachary”
                                          lastname: “Pinter”
        id: 2
                                          addresses: [
        label: “home”                       AddressVO(instance A)
        line1: “6666 W 66th Ave”             id: 2
        city: “Denver”                       label: “home”
        state: “CO”                          line1: “6666 W 66th Ave”
                                             city: “Denver”
                                             state: “CO”
     The AddressVO in the cache is         AddressVO
     updated and the AddressVO in            id: 3
     UserVO.addresses is replaced with       label: “work”
     the instance from the cache.            line1: “5555 W 55th Ave”
                                             city: “Denver”
                                             state: “CO”]

19
Updating the Cache
     Code looks something like this...

     if (obj is Array) {
        var arr:Array = obj as Array;
        for (var i:int=0;i<arr.length;i++) {
           if (arr[i] is BaseVO) {
              var res:BaseVO = updateEntity(arr[i] as BaseVO,...);
              if (res != null) arr[i] = res;
           }
        }
     }




20
Updating the Cache
     ArrayCollection’s are slightly trickier

     if (obj is ArrayCollection) {
        var ac:ArrayCollection = obj as ArrayCollection;
        ac.disableAutoUpdate();
        for (i=0;i<ac.length;i++) {
           if (ac.getItemAt(i) is BaseVO) {
              var res:BaseVO = updateEntity(ac.getItemAt(i) as BaseVO,...);
              if (res != null) {
                 ac.setItemAt(res,i);
              }
           }
        }
        ac.enableAutoUpdate();
     }




21
Now that we’ve added
     an entity to the cache...




22
The Cache
     How do we get an entity?
     What happens if we ask for an entity that isn’t in the cache?

     public class EntityCache
     {

         public function getEntity(id:String):EntityWrapper
         {
            //...
         }

     }




23
EntityWrapper
     [Bindable]
                                                    When requesting an entity, a
     public class EntityWrapper                     wrapper object is returned.
     {
        public var entityId:String;                 If that object is in the cache,
        public var entity:BaseVO;                   EntityWrapper.entity will have a
                                                    value.
         public function EntityWrapper(id:String)
         {                                          If the object is not in the cache,
            entityId = id;
         }                                          EntityWrapper.entity will be null
                                                    and a call to fetch the entity will
     }                                              be queued.




24
Using the Cache

     userWrapper = cache.getEntity(userid.text);


     <mx:Label text=quot;Username: {userWrapper.entity.username}quot;/>




25
Using the Cache - List Renderers
     Benefits
      ‣ Faster initial query since you’re only grabbing the id’s
      ‣ Rows are lazy-fetched as you scroll

     Drawbacks
      ‣ Sorting has to be handled by the server




26
Using the Cache - List Renderers
     What’s the code for the item renderer look like?



     override public function set data(val:Object):void
     {
        if(val != data){
           if (!val) {
              wrapper = null;
           } else {
              wrapper = cache.getEntity(val);
           }
           super.data = val;
        }
     }




27
Serverside Considerations




              What does this require of your
                backend infrastructure?




28
Serverside Considerations




                 Globally Unique Keys




29
Dictionary Keys
     Only one cache, need to prevent collisions
     Some Options:
       ‣ Globally unique sequence across all tables (UserVO with id 1, AddressVO with id 2)
       ‣ UUID’s (great for generating new id’s flex-side)
       ‣ Combine type with id (“UserVO-1”, “AddressVO-1”)




30
Serverside Considerations




             Ability to get an entity by its key




31
Serverside Considerations




            Ability to query for entities and only
            return their keys (used by lazy lists)




32
Bonus




33
Serverside Considerations


             Ability to get multiple entities in a
            single call by passing multiple keys




34
Serverside Considerations


             Ability to get multiple entities in a
            single call by passing multiple keys




35
Serverside Considerations




                   Versioned Entities




36
Demo




37
Questions?




38
Thanks!
     Zachary Pinter
     http://github.com/zpinter/cache-sync
     http://slideshare.net/zpinter
     http://zacharypinter.com
     http://effectiveui.com
     Twitter: zpinter




     Want to work for a cool company? We’re hiring!
     http://jobs.effectiveui.com/

39

More Related Content

What's hot

Doctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document MapperDoctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document Mapper
Jonathan Wage
 
Symfony Day 2010 Doctrine MongoDB ODM
Symfony Day 2010 Doctrine MongoDB ODMSymfony Day 2010 Doctrine MongoDB ODM
Symfony Day 2010 Doctrine MongoDB ODM
Jonathan Wage
 
Persistent Memoization with HTML5 indexedDB and jQuery Promises
Persistent Memoization with HTML5 indexedDB and jQuery PromisesPersistent Memoization with HTML5 indexedDB and jQuery Promises
Persistent Memoization with HTML5 indexedDB and jQuery Promises
Ray Bellis
 
2001: JNDI Its all in the Context
2001:  JNDI Its all in the Context2001:  JNDI Its all in the Context
2001: JNDI Its all in the Context
Russell Castagnaro
 
Hidden Treasures of the Python Standard Library
Hidden Treasures of the Python Standard LibraryHidden Treasures of the Python Standard Library
Hidden Treasures of the Python Standard Library
doughellmann
 
What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?
Trisha Gee
 
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needDutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Kacper Gunia
 
Java libraries you can't afford to miss
Java libraries you can't afford to missJava libraries you can't afford to miss
Java libraries you can't afford to miss
Andres Almiray
 
Couchdb: No SQL? No driver? No problem
Couchdb: No SQL? No driver? No problemCouchdb: No SQL? No driver? No problem
Couchdb: No SQL? No driver? No problem
delagoya
 
¿Cómo de sexy puede hacer Backbone mi código?
¿Cómo de sexy puede hacer Backbone mi código?¿Cómo de sexy puede hacer Backbone mi código?
¿Cómo de sexy puede hacer Backbone mi código?
jaespinmora
 
Custom deployments with sbt-native-packager
Custom deployments with sbt-native-packagerCustom deployments with sbt-native-packager
Custom deployments with sbt-native-packager
GaryCoady
 

What's hot (11)

Doctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document MapperDoctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document Mapper
 
Symfony Day 2010 Doctrine MongoDB ODM
Symfony Day 2010 Doctrine MongoDB ODMSymfony Day 2010 Doctrine MongoDB ODM
Symfony Day 2010 Doctrine MongoDB ODM
 
Persistent Memoization with HTML5 indexedDB and jQuery Promises
Persistent Memoization with HTML5 indexedDB and jQuery PromisesPersistent Memoization with HTML5 indexedDB and jQuery Promises
Persistent Memoization with HTML5 indexedDB and jQuery Promises
 
2001: JNDI Its all in the Context
2001:  JNDI Its all in the Context2001:  JNDI Its all in the Context
2001: JNDI Its all in the Context
 
Hidden Treasures of the Python Standard Library
Hidden Treasures of the Python Standard LibraryHidden Treasures of the Python Standard Library
Hidden Treasures of the Python Standard Library
 
What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?
 
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needDutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
 
Java libraries you can't afford to miss
Java libraries you can't afford to missJava libraries you can't afford to miss
Java libraries you can't afford to miss
 
Couchdb: No SQL? No driver? No problem
Couchdb: No SQL? No driver? No problemCouchdb: No SQL? No driver? No problem
Couchdb: No SQL? No driver? No problem
 
¿Cómo de sexy puede hacer Backbone mi código?
¿Cómo de sexy puede hacer Backbone mi código?¿Cómo de sexy puede hacer Backbone mi código?
¿Cómo de sexy puede hacer Backbone mi código?
 
Custom deployments with sbt-native-packager
Custom deployments with sbt-native-packagerCustom deployments with sbt-native-packager
Custom deployments with sbt-native-packager
 

Similar to Caching and Synchronization in Flex

Intro to Cocoa KVC/KVO and Bindings
Intro to Cocoa KVC/KVO and BindingsIntro to Cocoa KVC/KVO and Bindings
Intro to Cocoa KVC/KVO and Bindings
Sergio Acosta
 
Vidoop CouchDB Talk
Vidoop CouchDB TalkVidoop CouchDB Talk
Vidoop CouchDB Talk
Chris Anderson
 
DPC2007 PHP And Oracle (Kuassi Mensah)
DPC2007 PHP And Oracle (Kuassi Mensah)DPC2007 PHP And Oracle (Kuassi Mensah)
DPC2007 PHP And Oracle (Kuassi Mensah)
dpc
 
You're Off the Hook: Blinding Security Software
You're Off the Hook: Blinding Security SoftwareYou're Off the Hook: Blinding Security Software
You're Off the Hook: Blinding Security Software
Cylance
 
Industroyer: biggest threat to industrial control systems since Stuxnet by An...
Industroyer: biggest threat to industrial control systems since Stuxnet by An...Industroyer: biggest threat to industrial control systems since Stuxnet by An...
Industroyer: biggest threat to industrial control systems since Stuxnet by An...
CODE BLUE
 
How Scala code is expressed in the JVM
How Scala code is expressed in the JVMHow Scala code is expressed in the JVM
How Scala code is expressed in the JVM
Koichi Sakata
 
20101017 program analysis_for_security_livshits_lecture04_nozzle
20101017 program analysis_for_security_livshits_lecture04_nozzle20101017 program analysis_for_security_livshits_lecture04_nozzle
20101017 program analysis_for_security_livshits_lecture04_nozzle
Computer Science Club
 
Javascript The Good Parts
Javascript The Good PartsJavascript The Good Parts
Javascript The Good Parts
Federico Galassi
 
Quick Intro To JRuby
Quick Intro To JRubyQuick Intro To JRuby
Quick Intro To JRuby
Frederic Jean
 
Pyruvate, a reasonably fast, non-blocking, multithreaded WSGI server
Pyruvate, a reasonably fast, non-blocking, multithreaded WSGI serverPyruvate, a reasonably fast, non-blocking, multithreaded WSGI server
Pyruvate, a reasonably fast, non-blocking, multithreaded WSGI server
PloneFoundation
 
MySQL Proxy tutorial
MySQL Proxy tutorialMySQL Proxy tutorial
MySQL Proxy tutorial
Giuseppe Maxia
 
Ugo Cei Presentation
Ugo Cei PresentationUgo Cei Presentation
Ugo Cei Presentation
RubyOnRails_dude
 
javascript teach
javascript teachjavascript teach
javascript teach
guest3732fa
 
JSBootcamp_White
JSBootcamp_WhiteJSBootcamp_White
JSBootcamp_White
guest3732fa
 
Building a JavaScript Library
Building a JavaScript LibraryBuilding a JavaScript Library
Building a JavaScript Library
jeresig
 
Windows Azure Storage
Windows Azure StorageWindows Azure Storage
Windows Azure Storage
goodfriday
 
BADCamp 2008 DB Sync
BADCamp 2008 DB SyncBADCamp 2008 DB Sync
BADCamp 2008 DB Sync
Shaun Haber
 
Grizzly1.9.3x
Grizzly1.9.3xGrizzly1.9.3x
Grizzly1.9.3x
Yoshio Terada
 
Ruby 2.4 Internals
Ruby 2.4 InternalsRuby 2.4 Internals
Ruby 2.4 Internals
Koichi Sasada
 
17-Networking.pdf
17-Networking.pdf17-Networking.pdf
17-Networking.pdf
sophia763824
 

Similar to Caching and Synchronization in Flex (20)

Intro to Cocoa KVC/KVO and Bindings
Intro to Cocoa KVC/KVO and BindingsIntro to Cocoa KVC/KVO and Bindings
Intro to Cocoa KVC/KVO and Bindings
 
Vidoop CouchDB Talk
Vidoop CouchDB TalkVidoop CouchDB Talk
Vidoop CouchDB Talk
 
DPC2007 PHP And Oracle (Kuassi Mensah)
DPC2007 PHP And Oracle (Kuassi Mensah)DPC2007 PHP And Oracle (Kuassi Mensah)
DPC2007 PHP And Oracle (Kuassi Mensah)
 
You're Off the Hook: Blinding Security Software
You're Off the Hook: Blinding Security SoftwareYou're Off the Hook: Blinding Security Software
You're Off the Hook: Blinding Security Software
 
Industroyer: biggest threat to industrial control systems since Stuxnet by An...
Industroyer: biggest threat to industrial control systems since Stuxnet by An...Industroyer: biggest threat to industrial control systems since Stuxnet by An...
Industroyer: biggest threat to industrial control systems since Stuxnet by An...
 
How Scala code is expressed in the JVM
How Scala code is expressed in the JVMHow Scala code is expressed in the JVM
How Scala code is expressed in the JVM
 
20101017 program analysis_for_security_livshits_lecture04_nozzle
20101017 program analysis_for_security_livshits_lecture04_nozzle20101017 program analysis_for_security_livshits_lecture04_nozzle
20101017 program analysis_for_security_livshits_lecture04_nozzle
 
Javascript The Good Parts
Javascript The Good PartsJavascript The Good Parts
Javascript The Good Parts
 
Quick Intro To JRuby
Quick Intro To JRubyQuick Intro To JRuby
Quick Intro To JRuby
 
Pyruvate, a reasonably fast, non-blocking, multithreaded WSGI server
Pyruvate, a reasonably fast, non-blocking, multithreaded WSGI serverPyruvate, a reasonably fast, non-blocking, multithreaded WSGI server
Pyruvate, a reasonably fast, non-blocking, multithreaded WSGI server
 
MySQL Proxy tutorial
MySQL Proxy tutorialMySQL Proxy tutorial
MySQL Proxy tutorial
 
Ugo Cei Presentation
Ugo Cei PresentationUgo Cei Presentation
Ugo Cei Presentation
 
javascript teach
javascript teachjavascript teach
javascript teach
 
JSBootcamp_White
JSBootcamp_WhiteJSBootcamp_White
JSBootcamp_White
 
Building a JavaScript Library
Building a JavaScript LibraryBuilding a JavaScript Library
Building a JavaScript Library
 
Windows Azure Storage
Windows Azure StorageWindows Azure Storage
Windows Azure Storage
 
BADCamp 2008 DB Sync
BADCamp 2008 DB SyncBADCamp 2008 DB Sync
BADCamp 2008 DB Sync
 
Grizzly1.9.3x
Grizzly1.9.3xGrizzly1.9.3x
Grizzly1.9.3x
 
Ruby 2.4 Internals
Ruby 2.4 InternalsRuby 2.4 Internals
Ruby 2.4 Internals
 
17-Networking.pdf
17-Networking.pdf17-Networking.pdf
17-Networking.pdf
 

Recently uploaded

“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
Edge AI and Vision Alliance
 
Apps Break Data
Apps Break DataApps Break Data
Apps Break Data
Ivo Velitchkov
 
June Patch Tuesday
June Patch TuesdayJune Patch Tuesday
June Patch Tuesday
Ivanti
 
Mutation Testing for Task-Oriented Chatbots
Mutation Testing for Task-Oriented ChatbotsMutation Testing for Task-Oriented Chatbots
Mutation Testing for Task-Oriented Chatbots
Pablo Gómez Abajo
 
Programming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup SlidesProgramming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup Slides
Zilliz
 
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
saastr
 
Harnessing the Power of NLP and Knowledge Graphs for Opioid Research
Harnessing the Power of NLP and Knowledge Graphs for Opioid ResearchHarnessing the Power of NLP and Knowledge Graphs for Opioid Research
Harnessing the Power of NLP and Knowledge Graphs for Opioid Research
Neo4j
 
Principle of conventional tomography-Bibash Shahi ppt..pptx
Principle of conventional tomography-Bibash Shahi ppt..pptxPrinciple of conventional tomography-Bibash Shahi ppt..pptx
Principle of conventional tomography-Bibash Shahi ppt..pptx
BibashShahi
 
“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...
“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...
“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...
Edge AI and Vision Alliance
 
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
saastr
 
Essentials of Automations: Exploring Attributes & Automation Parameters
Essentials of Automations: Exploring Attributes & Automation ParametersEssentials of Automations: Exploring Attributes & Automation Parameters
Essentials of Automations: Exploring Attributes & Automation Parameters
Safe Software
 
What is an RPA CoE? Session 1 – CoE Vision
What is an RPA CoE?  Session 1 – CoE VisionWhat is an RPA CoE?  Session 1 – CoE Vision
What is an RPA CoE? Session 1 – CoE Vision
DianaGray10
 
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdfMonitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Tosin Akinosho
 
GNSS spoofing via SDR (Criptored Talks 2024)
GNSS spoofing via SDR (Criptored Talks 2024)GNSS spoofing via SDR (Criptored Talks 2024)
GNSS spoofing via SDR (Criptored Talks 2024)
Javier Junquera
 
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-EfficiencyFreshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
ScyllaDB
 
HCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAUHCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAU
panagenda
 
Dandelion Hashtable: beyond billion requests per second on a commodity server
Dandelion Hashtable: beyond billion requests per second on a commodity serverDandelion Hashtable: beyond billion requests per second on a commodity server
Dandelion Hashtable: beyond billion requests per second on a commodity server
Antonios Katsarakis
 
"Choosing proper type of scaling", Olena Syrota
"Choosing proper type of scaling", Olena Syrota"Choosing proper type of scaling", Olena Syrota
"Choosing proper type of scaling", Olena Syrota
Fwdays
 
Connector Corner: Seamlessly power UiPath Apps, GenAI with prebuilt connectors
Connector Corner: Seamlessly power UiPath Apps, GenAI with prebuilt connectorsConnector Corner: Seamlessly power UiPath Apps, GenAI with prebuilt connectors
Connector Corner: Seamlessly power UiPath Apps, GenAI with prebuilt connectors
DianaGray10
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
Jason Packer
 

Recently uploaded (20)

“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
 
Apps Break Data
Apps Break DataApps Break Data
Apps Break Data
 
June Patch Tuesday
June Patch TuesdayJune Patch Tuesday
June Patch Tuesday
 
Mutation Testing for Task-Oriented Chatbots
Mutation Testing for Task-Oriented ChatbotsMutation Testing for Task-Oriented Chatbots
Mutation Testing for Task-Oriented Chatbots
 
Programming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup SlidesProgramming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup Slides
 
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
 
Harnessing the Power of NLP and Knowledge Graphs for Opioid Research
Harnessing the Power of NLP and Knowledge Graphs for Opioid ResearchHarnessing the Power of NLP and Knowledge Graphs for Opioid Research
Harnessing the Power of NLP and Knowledge Graphs for Opioid Research
 
Principle of conventional tomography-Bibash Shahi ppt..pptx
Principle of conventional tomography-Bibash Shahi ppt..pptxPrinciple of conventional tomography-Bibash Shahi ppt..pptx
Principle of conventional tomography-Bibash Shahi ppt..pptx
 
“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...
“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...
“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...
 
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
 
Essentials of Automations: Exploring Attributes & Automation Parameters
Essentials of Automations: Exploring Attributes & Automation ParametersEssentials of Automations: Exploring Attributes & Automation Parameters
Essentials of Automations: Exploring Attributes & Automation Parameters
 
What is an RPA CoE? Session 1 – CoE Vision
What is an RPA CoE?  Session 1 – CoE VisionWhat is an RPA CoE?  Session 1 – CoE Vision
What is an RPA CoE? Session 1 – CoE Vision
 
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdfMonitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdf
 
GNSS spoofing via SDR (Criptored Talks 2024)
GNSS spoofing via SDR (Criptored Talks 2024)GNSS spoofing via SDR (Criptored Talks 2024)
GNSS spoofing via SDR (Criptored Talks 2024)
 
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-EfficiencyFreshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
Freshworks Rethinks NoSQL for Rapid Scaling & Cost-Efficiency
 
HCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAUHCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAU
 
Dandelion Hashtable: beyond billion requests per second on a commodity server
Dandelion Hashtable: beyond billion requests per second on a commodity serverDandelion Hashtable: beyond billion requests per second on a commodity server
Dandelion Hashtable: beyond billion requests per second on a commodity server
 
"Choosing proper type of scaling", Olena Syrota
"Choosing proper type of scaling", Olena Syrota"Choosing proper type of scaling", Olena Syrota
"Choosing proper type of scaling", Olena Syrota
 
Connector Corner: Seamlessly power UiPath Apps, GenAI with prebuilt connectors
Connector Corner: Seamlessly power UiPath Apps, GenAI with prebuilt connectorsConnector Corner: Seamlessly power UiPath Apps, GenAI with prebuilt connectors
Connector Corner: Seamlessly power UiPath Apps, GenAI with prebuilt connectors
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
 

Caching and Synchronization in Flex

  • 1. Caching and Synchronization in Flex Zachary Pinter Senior Developer EffectiveUI 360Flex 1
  • 2. The Problem How do we keep live (changing) server data synchronized across multiple views and multiple users? 2
  • 3. The Approach Fetch entities only once and only when needed. 3
  • 4. The Approach One definitive instance of a server- side entity. 4
  • 5. The Approach Update all relevant views when the server sends notice that an entity has changed. 5
  • 6. The Approach Server-side agnostic. 6
  • 7. What’s the strategy? Store all fetched entities in a single cache (Dictionary). 7
  • 8. What’s the strategy? Bind the views to the cache. 8
  • 9. What about memory use? public class WeakReference Allows cache values to be { garbage-collected if they’re not being referenced anywhere else. private var dic:Dictionary; public function WeakReference(obj:*) { dic = new Dictionary(true); Text dic[obj] = 1; } public function getValue():* { for (var item:* in dic) { return item; } return null; } } 9
  • 10. The Cache How do we add an entity to the cache? public class EntityCache { public function updateEntity(entity:BaseVO, ...):BaseVO { //... } } 10
  • 11. Recurse through properties Adding a user to the cache also adds its address. UserVO id: 1 firstname: “Zachary” lastname: “Pinter” EntityCache address: 1: UserVO AddressVO 2: AddressVO id: 2 line1: “4444 W 44th Ave” city: “Denver” state: “CO” 11
  • 12. Recurse through properties Arrays behave the same way UserVO id: 1 firstname: “Zachary” lastname: “Pinter” addresses: [ EntityCache AddressVO 1: UserVO id: 2 label: “home” 2: AddressVO line1: “4444 W 44th Ave” 3: AddressVO city: “Denver” state: “CO” AddressVO id: 3 label: “work” line1: “5555 W 55th Ave” city: “Denver” state: “CO”] 12
  • 13. Finding an object’s properties Spring Actionscript (formally Prana) http://www.pranaframework.org/ var type:Type = Type.forName(classname); for each (var accessor:Accessor in type.accessors) { if (accessor.isStatic == false && accessor.access.name == quot;readwritequot;) { result.push(accessor.name); } } return result; 13
  • 14. Finding an object’s properties Source generator public class UserVO extends BaseVO { public var username : String; public var firstname : String; public var lastname : String; public var address : AddressVO; override public function getProperties():Array { return super.getProperties().concat(quot;usernamequot;,quot;firstnamequot;,quot;lastnamequot;,quot;addressquot;); } } 14
  • 15. Updating the cache What if the entity is already in the cache? EntityCache EntityCache.updateEntity( 1: UserVO(instance A) UserVO(instance B) id: 1 id: 1 firstname: “Robert” firstname: “Bob” lastname: “Smith” lastname: “Smith” ) Copy the properties from instance B into instance A EntityCache Leave instance A in the 1: UserVO(instance A) cache id: 1 firstname: “Bob” Discard instance B lastname: “Smith” 15
  • 16. Updating the cache What about arrays? EntityCache UserVO id: 1 firstname: “Zachary” lastname: “Pinter” EntityCache.updateEntity( addresses: [ AddressVO(instance B) AddressVO(instance A) id: 2 id: 2 label: “home” label: “home” line1: “4444 W 44th Ave” line1: “3333 W 33rd Ave” city: “Denver” city: “Denver” state: “CO” state: “CO” AddressVO ) id: 3 label: “work” line1: “5555 W 55th Ave” city: “Denver” state: “CO”] 16
  • 17. Updating the cache What about arrays? UserVO id: 1 Since we update the existing instance, firstname: “Zachary” all references to it will see the update. lastname: “Pinter” addresses: [ AddressVO(instance A) id: 2 label: “home” line1: “3333 W 33rd Ave” city: “Denver” state: “CO” AddressVO id: 3 label: “work” line1: “5555 W 55th Ave” city: “Denver” state: “CO”] 17
  • 18. Updating the Cache The flip side UserVO EntityCache id: 5 AddressVO(instance A) firstname: “Zachary” lastname: “Pinter” id: 2 addresses: [ label: “home” AddressVO(instance B) line1: “5555 W 55th Ave” id: 2 city: “Denver” label: “home” state: “CO” line1: “6666 W 66th Ave” city: “Denver” state: “CO” Your cache already has an AddressVO AddressVO with id 2 in it, and you id: 3 add a new UserVO to the cache that label: “work” references an updated instance of the line1: “5555 W 55th Ave” AddressVO city: “Denver” state: “CO”] 18
  • 19. Updating the Cache UserVO EntityCache id: 5 AddressVO(instance A) firstname: “Zachary” lastname: “Pinter” id: 2 addresses: [ label: “home” AddressVO(instance A) line1: “6666 W 66th Ave” id: 2 city: “Denver” label: “home” state: “CO” line1: “6666 W 66th Ave” city: “Denver” state: “CO” The AddressVO in the cache is AddressVO updated and the AddressVO in id: 3 UserVO.addresses is replaced with label: “work” the instance from the cache. line1: “5555 W 55th Ave” city: “Denver” state: “CO”] 19
  • 20. Updating the Cache Code looks something like this... if (obj is Array) { var arr:Array = obj as Array; for (var i:int=0;i<arr.length;i++) { if (arr[i] is BaseVO) { var res:BaseVO = updateEntity(arr[i] as BaseVO,...); if (res != null) arr[i] = res; } } } 20
  • 21. Updating the Cache ArrayCollection’s are slightly trickier if (obj is ArrayCollection) { var ac:ArrayCollection = obj as ArrayCollection; ac.disableAutoUpdate(); for (i=0;i<ac.length;i++) { if (ac.getItemAt(i) is BaseVO) { var res:BaseVO = updateEntity(ac.getItemAt(i) as BaseVO,...); if (res != null) { ac.setItemAt(res,i); } } } ac.enableAutoUpdate(); } 21
  • 22. Now that we’ve added an entity to the cache... 22
  • 23. The Cache How do we get an entity? What happens if we ask for an entity that isn’t in the cache? public class EntityCache { public function getEntity(id:String):EntityWrapper { //... } } 23
  • 24. EntityWrapper [Bindable] When requesting an entity, a public class EntityWrapper wrapper object is returned. { public var entityId:String; If that object is in the cache, public var entity:BaseVO; EntityWrapper.entity will have a value. public function EntityWrapper(id:String) { If the object is not in the cache, entityId = id; } EntityWrapper.entity will be null and a call to fetch the entity will } be queued. 24
  • 25. Using the Cache userWrapper = cache.getEntity(userid.text); <mx:Label text=quot;Username: {userWrapper.entity.username}quot;/> 25
  • 26. Using the Cache - List Renderers Benefits ‣ Faster initial query since you’re only grabbing the id’s ‣ Rows are lazy-fetched as you scroll Drawbacks ‣ Sorting has to be handled by the server 26
  • 27. Using the Cache - List Renderers What’s the code for the item renderer look like? override public function set data(val:Object):void { if(val != data){ if (!val) { wrapper = null; } else { wrapper = cache.getEntity(val); } super.data = val; } } 27
  • 28. Serverside Considerations What does this require of your backend infrastructure? 28
  • 29. Serverside Considerations Globally Unique Keys 29
  • 30. Dictionary Keys Only one cache, need to prevent collisions Some Options: ‣ Globally unique sequence across all tables (UserVO with id 1, AddressVO with id 2) ‣ UUID’s (great for generating new id’s flex-side) ‣ Combine type with id (“UserVO-1”, “AddressVO-1”) 30
  • 31. Serverside Considerations Ability to get an entity by its key 31
  • 32. Serverside Considerations Ability to query for entities and only return their keys (used by lazy lists) 32
  • 34. Serverside Considerations Ability to get multiple entities in a single call by passing multiple keys 34
  • 35. Serverside Considerations Ability to get multiple entities in a single call by passing multiple keys 35
  • 36. Serverside Considerations Versioned Entities 36
  • 39. Thanks! Zachary Pinter http://github.com/zpinter/cache-sync http://slideshare.net/zpinter http://zacharypinter.com http://effectiveui.com Twitter: zpinter Want to work for a cool company? We’re hiring! http://jobs.effectiveui.com/ 39