Caching and Synchronization in Flex

4,243 views

Published on

A presentation about managing serverside entities in Flex.

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
4,243
On SlideShare
0
From Embeds
0
Number of Embeds
39
Actions
Shares
0
Downloads
64
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Caching and Synchronization in Flex

  1. 1. Caching and Synchronization in Flex Zachary Pinter Senior Developer EffectiveUI 360Flex 1
  2. 2. The Problem How do we keep live (changing) server data synchronized across multiple views and multiple users? 2
  3. 3. The Approach Fetch entities only once and only when needed. 3
  4. 4. The Approach One definitive instance of a server- side entity. 4
  5. 5. The Approach Update all relevant views when the server sends notice that an entity has changed. 5
  6. 6. The Approach Server-side agnostic. 6
  7. 7. What’s the strategy? Store all fetched entities in a single cache (Dictionary). 7
  8. 8. What’s the strategy? Bind the views to the cache. 8
  9. 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. 10. The Cache How do we add an entity to the cache? public class EntityCache { public function updateEntity(entity:BaseVO, ...):BaseVO { //... } } 10
  11. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 22. Now that we’ve added an entity to the cache... 22
  23. 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. 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. 25. Using the Cache userWrapper = cache.getEntity(userid.text); <mx:Label text=quot;Username: {userWrapper.entity.username}quot;/> 25
  26. 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. 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. 28. Serverside Considerations What does this require of your backend infrastructure? 28
  29. 29. Serverside Considerations Globally Unique Keys 29
  30. 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. 31. Serverside Considerations Ability to get an entity by its key 31
  32. 32. Serverside Considerations Ability to query for entities and only return their keys (used by lazy lists) 32
  33. 33. Bonus 33
  34. 34. Serverside Considerations Ability to get multiple entities in a single call by passing multiple keys 34
  35. 35. Serverside Considerations Ability to get multiple entities in a single call by passing multiple keys 35
  36. 36. Serverside Considerations Versioned Entities 36
  37. 37. Demo 37
  38. 38. Questions? 38
  39. 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

×