![Page 1: Zach Pinter - Caching and Synchronization with Flex](https://reader037.vdocuments.us/reader037/viewer/2022102922/54b48b2f4a7959da6c8b4629/html5/thumbnails/1.jpg)
Caching and Synchronization in Flex
1
Zachary PinterSenior DeveloperEffectiveUI360Flex
![Page 2: Zach Pinter - Caching and Synchronization with Flex](https://reader037.vdocuments.us/reader037/viewer/2022102922/54b48b2f4a7959da6c8b4629/html5/thumbnails/2.jpg)
The ProblemCommon application data shown in multiple views, being manipulated by multiple users at roughly the same time.
2
![Page 3: Zach Pinter - Caching and Synchronization with Flex](https://reader037.vdocuments.us/reader037/viewer/2022102922/54b48b2f4a7959da6c8b4629/html5/thumbnails/3.jpg)
GoalsFetch entities only once and only as needed.
One definitive instance of a server-side entity.
Update all relevant views when the server sends notice that an entity has changed.
Server-side agnostic.
3
![Page 4: Zach Pinter - Caching and Synchronization with Flex](https://reader037.vdocuments.us/reader037/viewer/2022102922/54b48b2f4a7959da6c8b4629/html5/thumbnails/4.jpg)
What’s the strategy?Store all fetched entities in a single cache (Dictionary).
Bind the views to the cache.
4
![Page 5: Zach Pinter - Caching and Synchronization with Flex](https://reader037.vdocuments.us/reader037/viewer/2022102922/54b48b2f4a7959da6c8b4629/html5/thumbnails/5.jpg)
What about memory use?
5
public class WeakReference{ private var dic:Dictionary; public function WeakReference(obj:*) { dic = new Dictionary(true); dic[obj] = 1; } public function getValue():* { for (var item:* in dic) { return item; } return null; }
}
Text
Allows cache values to be garbage-collected if they’re not being referenced anywhere else.
![Page 6: Zach Pinter - Caching and Synchronization with Flex](https://reader037.vdocuments.us/reader037/viewer/2022102922/54b48b2f4a7959da6c8b4629/html5/thumbnails/6.jpg)
The CacheHow do we add an entity to the cache?
6
public class EntityCache{ public function updateEntity(entity:BaseVO, ...):BaseVO { //... }}
![Page 7: Zach Pinter - Caching and Synchronization with Flex](https://reader037.vdocuments.us/reader037/viewer/2022102922/54b48b2f4a7959da6c8b4629/html5/thumbnails/7.jpg)
Recurse through properties
UserVO id: 1 firstname: “Zachary” lastname: “Pinter” address: AddressVO id: 2 line1: “4444 W 44th Ave” city: “Denver” state: “CO”
7
EntityCache 1: UserVO 2: AddressVO
Adding a user to the cache also adds its address.
![Page 8: Zach Pinter - Caching and Synchronization with Flex](https://reader037.vdocuments.us/reader037/viewer/2022102922/54b48b2f4a7959da6c8b4629/html5/thumbnails/8.jpg)
Recurse through properties
UserVO id: 1 firstname: “Zachary” lastname: “Pinter” addresses: [ AddressVO id: 2 label: “home” line1: “4444 W 44th Ave” city: “Denver” state: “CO” AddressVO id: 3 label: “work” line1: “5555 W 55th Ave” city: “Denver” state: “CO”]
8
EntityCache 1: UserVO 2: AddressVO 3: AddressVO
Arrays behave the same way
![Page 9: Zach Pinter - Caching and Synchronization with Flex](https://reader037.vdocuments.us/reader037/viewer/2022102922/54b48b2f4a7959da6c8b4629/html5/thumbnails/9.jpg)
Finding an object’s propertiesSpring Actionscript (formally Prana)
http://www.pranaframework.org/
9
var type:Type = Type.forName(classname); for each (var accessor:Accessor in type.accessors) { if (accessor.isStatic == false && accessor.access.name == "readwrite") { result.push(accessor.name); }}return result;
![Page 10: Zach Pinter - Caching and Synchronization with Flex](https://reader037.vdocuments.us/reader037/viewer/2022102922/54b48b2f4a7959da6c8b4629/html5/thumbnails/10.jpg)
Finding an object’s propertiesSource generator
10
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("username","firstname","lastname","address"); }}
![Page 11: Zach Pinter - Caching and Synchronization with Flex](https://reader037.vdocuments.us/reader037/viewer/2022102922/54b48b2f4a7959da6c8b4629/html5/thumbnails/11.jpg)
Updating the cacheWhat if the entity is already in the cache?
11
EntityCache 1: UserVO(instance A) id: 1 firstname: “Robert” lastname: “Smith”
EntityCache.updateEntity( UserVO(instance B) id: 1 firstname: “Bob” lastname: “Smith” )
EntityCache 1: UserVO(instance A) id: 1 firstname: “Bob” lastname: “Smith”
Copy the properties from instance B into instance A
Leave instance A in the cache
Discard instance B
![Page 12: Zach Pinter - Caching and Synchronization with Flex](https://reader037.vdocuments.us/reader037/viewer/2022102922/54b48b2f4a7959da6c8b4629/html5/thumbnails/12.jpg)
Updating the cacheWhat about arrays?
12
EntityCache UserVO id: 1 firstname: “Zachary” lastname: “Pinter” addresses: [ AddressVO(instance A) id: 2 label: “home” line1: “4444 W 44th Ave” city: “Denver” state: “CO” AddressVO id: 3 label: “work” line1: “5555 W 55th Ave” city: “Denver” state: “CO”]
EntityCache.updateEntity( AddressVO(instance B) id: 2 label: “home” line1: “3333 W 33rd Ave” city: “Denver” state: “CO” )
![Page 13: Zach Pinter - Caching and Synchronization with Flex](https://reader037.vdocuments.us/reader037/viewer/2022102922/54b48b2f4a7959da6c8b4629/html5/thumbnails/13.jpg)
Updating the cacheWhat about arrays?
13
UserVO id: 1 firstname: “Zachary” 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”]
Since we update the existing instance, all references to it will see the update.
![Page 14: Zach Pinter - Caching and Synchronization with Flex](https://reader037.vdocuments.us/reader037/viewer/2022102922/54b48b2f4a7959da6c8b4629/html5/thumbnails/14.jpg)
Updating the CacheThe flip side
14
UserVO id: 5 firstname: “Zachary” lastname: “Pinter” addresses: [ AddressVO(instance B) id: 2 label: “home” line1: “6666 W 66th Ave” city: “Denver” state: “CO” AddressVO id: 3 label: “work” line1: “5555 W 55th Ave” city: “Denver” state: “CO”]
EntityCache AddressVO(instance A) id: 2 label: “home” line1: “5555 W 55th Ave” city: “Denver” state: “CO”
Your cache already has an AddressVO with id 2 in it, and you add a new UserVO to the cache that references an updated instance of the AddressVO
![Page 15: Zach Pinter - Caching and Synchronization with Flex](https://reader037.vdocuments.us/reader037/viewer/2022102922/54b48b2f4a7959da6c8b4629/html5/thumbnails/15.jpg)
Updating the Cache
15
UserVO id: 5 firstname: “Zachary” lastname: “Pinter” addresses: [ AddressVO(instance A) id: 2 label: “home” line1: “6666 W 66th Ave” city: “Denver” state: “CO” AddressVO id: 3 label: “work” line1: “5555 W 55th Ave” city: “Denver” state: “CO”]
EntityCache AddressVO(instance A) id: 2 label: “home” line1: “6666 W 66th Ave” city: “Denver” state: “CO”
The AddressVO in the cache is updated and the AddressVO in UserVO.addresses is replaced with the instance from the cache.
![Page 16: Zach Pinter - Caching and Synchronization with Flex](https://reader037.vdocuments.us/reader037/viewer/2022102922/54b48b2f4a7959da6c8b4629/html5/thumbnails/16.jpg)
Updating the Cache
16
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; } }}
Code looks something like this...
![Page 17: Zach Pinter - Caching and Synchronization with Flex](https://reader037.vdocuments.us/reader037/viewer/2022102922/54b48b2f4a7959da6c8b4629/html5/thumbnails/17.jpg)
Updating the Cache
17
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();}
ArrayCollection’s are slightly trickier
![Page 18: Zach Pinter - Caching and Synchronization with Flex](https://reader037.vdocuments.us/reader037/viewer/2022102922/54b48b2f4a7959da6c8b4629/html5/thumbnails/18.jpg)
18
Now that we’ve added an entity to the cache...
![Page 19: Zach Pinter - Caching and Synchronization with Flex](https://reader037.vdocuments.us/reader037/viewer/2022102922/54b48b2f4a7959da6c8b4629/html5/thumbnails/19.jpg)
The CacheHow do we get an entity?
What happens if we ask for an entity that isn’t in the cache?
19
public class EntityCache{
public function getEntity(id:String):EntityWrapper { //... } }
![Page 20: Zach Pinter - Caching and Synchronization with Flex](https://reader037.vdocuments.us/reader037/viewer/2022102922/54b48b2f4a7959da6c8b4629/html5/thumbnails/20.jpg)
EntityWrapperWhen requesting an entity, a wrapper object is returned.
If that object is in the cache, EntityWrapper.entity will have a value.
If the object is not in the cache, EntityWrapper.entity will be null and a call to fetch the entity will be queued.
20
[Bindable]public class EntityWrapper{ public var entityId:String; public var entity:BaseVO; public function EntityWrapper(id:String) { entityId = id; } }
![Page 21: Zach Pinter - Caching and Synchronization with Flex](https://reader037.vdocuments.us/reader037/viewer/2022102922/54b48b2f4a7959da6c8b4629/html5/thumbnails/21.jpg)
Using the Cache
21
<mx:Label text="Username: {userWrapper.entity.username}"/>
userWrapper = cache.getEntity(userid.text);
![Page 22: Zach Pinter - Caching and Synchronization with Flex](https://reader037.vdocuments.us/reader037/viewer/2022102922/54b48b2f4a7959da6c8b4629/html5/thumbnails/22.jpg)
Using the Cache - List RenderersBenefits‣ 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
22
![Page 23: Zach Pinter - Caching and Synchronization with Flex](https://reader037.vdocuments.us/reader037/viewer/2022102922/54b48b2f4a7959da6c8b4629/html5/thumbnails/23.jpg)
Using the Cache - List RenderersWhat’s the code for the item renderer look like?
23
override public function set data(val:Object):void { if(val != data){ if (!val) { wrapper = null; } else { wrapper = cache.getEntity(val); } super.data = val; }}
![Page 24: Zach Pinter - Caching and Synchronization with Flex](https://reader037.vdocuments.us/reader037/viewer/2022102922/54b48b2f4a7959da6c8b4629/html5/thumbnails/24.jpg)
Serverside ConsiderationsWhat does this require of your backend infrastructure?‣ Globally unique keys (or a way to fake it)‣ Ability to get an entity by its key‣ Ability to query for entities and only return their keys (used by lazy lists)
Perks:‣ Versioned entities‣ Get multiple entities in a single call by passing multiple keys
24
![Page 25: Zach Pinter - Caching and Synchronization with Flex](https://reader037.vdocuments.us/reader037/viewer/2022102922/54b48b2f4a7959da6c8b4629/html5/thumbnails/25.jpg)
Dictionary KeysOnly 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”)
25
![Page 26: Zach Pinter - Caching and Synchronization with Flex](https://reader037.vdocuments.us/reader037/viewer/2022102922/54b48b2f4a7959da6c8b4629/html5/thumbnails/26.jpg)
26
Demo
![Page 27: Zach Pinter - Caching and Synchronization with Flex](https://reader037.vdocuments.us/reader037/viewer/2022102922/54b48b2f4a7959da6c8b4629/html5/thumbnails/27.jpg)
27
Questions?
![Page 28: Zach Pinter - Caching and Synchronization with Flex](https://reader037.vdocuments.us/reader037/viewer/2022102922/54b48b2f4a7959da6c8b4629/html5/thumbnails/28.jpg)
Thanks!Zachary Pinter
http://github.com/zpinter/cache-synchttp://slideshare.net/zpinterhttp://zacharypinter.comhttp://effectiveui.com
Twitter: zpinter
28