WWDC2004 Session 629

Transcript

Kind: captions Language: en good morning how's everybody doing this morning that's very exciting actually that's a half of that party last night I'd say that's a good energy level to have everybody enjoy the party last night just hear it free food well not free food but yeah food beer um welcome this is using webobjects eos and let's move this ahead 1 i'm james Dempsey I work at Apple I'm an operations engineer and Apple software customer seating as such I spend my days building a in maintaining to webobjects applications and also a cocoa administration ass all talking the same database prior to doing that I was in technical training so here I am for a friendly little chat about eof before we get started let me just do the old pole thing how many folks in the room our brand new to eof okay so we got a few folks excellent and how many folks would say you're intermediate okay great and how many your advanced folks are just here to make trouble oh yeah great excellent um okay so what we're going to be doing in this session to get rolling is we're going to do for folks are brand-new a bit of the basic so you get your mind around a little bit about what eof is about and then we're going to cover some advanced topics we're also going to do an architecture review which is helpful for the new folks but also I find that when you're talking about advanced topics it's really good to have kind of a picture of what's going on in eof clearly and freshly in your head so first let's do the basics review so the enterprise objects framework what is this thing so the basic idea is an object persistence framework largely the goal here is that you can look at it one of two ways either you have this lovely object-oriented webobjects application and then you need someplace over the network for the information that you've collected from users or want to display to users need a spot for that to persist in a relational database is a very good spot or the other way is usually more often you already have a database and you want to pull the information out but you'd like to deal with it in a nice object-oriented manner in a web objects application and eof fits the bill so it uses object relational mapping mapping will see in a moment from an object model to a relational database model and the goal or a goal is that rather than thinking a lot about what sequel joins am i doing and what foreign keys and all this kind of database specific stuff to try to use objects that you've gotten from the database in as 00 a manner as possible so in a nutshell we're going from a row in the database to an object and then make some changes to it maybe and then make sure it gets back in the correct state that in a nutshell is the crux of what eof is doing should be easy right all right so let's talk about some terms entities and attributes so an entity refers to essentially a class in your object model which will map to a table or view in the database and attribute is mapping a column in the table to a property or think of it as an instance variable in the object model and then relationships in an object model are typically done by reference in this case an employee is referring to one department but of course when we go to a database model we're using a join so a foreign key in this case in the employee table is mapping to the primary key of the department and its EOS job to allow you to work with objects largely in this fashion where you're setting the department of that employee and then when you save those of course you want it to translate to the proper join in the database so what r enterprise objects we talk what the framework is well you'll hear them refer to all the time as eos um all that that means largely is that they implement the EO Enterprise object interface typically you don't implement that interface yourself any of you troublemakers have you ever implemented the EO Enterprise object interface yourself no nobody nobody ever has comes with the framework you don't need to do so typically subclass EO generic record and put your own custom logic in there if you need to but largely you can think of an enterprise object as just an object like any other except having all the additional functionality to have built-in persistence now especially when you start first start working with eof the first thing you're going to encounter is defining a model to map between that object model and the relational database and we do that in a tool called EO modeler and we'll see a demo of it in a moment actually we will see it in a moment where my demo slide go well regardless seems to have disappeared let's cut over to demo one if we could alright we're going to build a model from scratch a tool called eel modeler we're going to use an existing database that a few of you might be familiar with so we connect using jdbc to a wide range of databases we just need a JDBC URL which I have let me click in the field there and we're using an open base database which has some examples including one that contains some movies and as we pick that URL yo modeler takes a peek into the database ask us a few things and we're just concerned about assigning primary keys to everything that gets pulled in and then we get a list of all the tables or going to choose movie as one of the tables but I don't know can anybody tell me what a movie might be related to that's right a studio every movie is related to a studio so we're going to pull in these two tables as we hit next and dismiss the wizard EO modeler has read the schema and reverse engineer the database and given us the beginnings of a model so if we take a look first at the model itself you'll notice that it is mapping a table name to a class name in this case a generic record which is a generic class that can be any type of entity as long as you don't need to add any custom behavior so we have a movie in a studio if we take a look at a movie you'll notice that a movie has various items here what's a pic one such as the title if we inspect it you'll notice that this attribute is mapping the name of this attribute to a particular column in the database in the database it's a car with a width of 255 internally we'll be using a string to represent this item and the same is true if we take a look at say a number or a date it's just a mapping between a column in the database and its data type and a name of an attribute in our object model and its data type and then finally we can take a look at a relationship looking at the foreign keys and primary key geo modeler has figured out that a movie is related to a studio in this case it has a 2-1 relationship and if we take a look you'll notice that it has already chosen a 2-1 it's related to a studio and it is mapping the foreign key the studio ID to the studio ID of the studio and once we set that joint information up in yo modeler at that point we no longer have to worry about those foreign keys and primary keys as eof will take care of that will say that as movies put it on the desktop and will close them all actually let's look at one other thing the fact that right here from you a modeler I can make sure that I do have a good connection to the database by browsing the model and I'm taking a look now at all of the movies that are in our database great okay now that's interesting but you're not going to give you a modeler out to everybody who wants to look in your database you're going to build a web application let's go to Xcode will make a small quick project will use a display group application since it will quickly build a user interface for us and walk through the wizard will call it demo whoa we're not going to deploy it in a servlet we're not going to use web services but we are going to use jdbc so that is the adapter will choose to connect to the database we don't need any additional frameworks but we do need to choose the model we just created pick that model choose it and now it'll ask us some questions regarding the first page of this application as we build its user interface so the movie entity let's get a table and matching records so we can do a search so don't get them all at once what attributes do we want to display let's display a couple first the title let's do the category what date it was released as well as how much revenue it took in and finally let's traverse that relationship to the related studio and display the studio's name and then let's search on the title and category of the movie let's finish it will build a project here in a moment there we go okay if we take a peek at this bring up the editor you'll notice that we really have no code going on here take a look at the application file a user session file just a constructor and then in a web objects application we use components to represent pages and in the main component which is the first one that's displayed in a web objects application we do not have any additional code except for some variables to hold a display group which displays the array of objects and the movie itself let's open up the component and web objects builder where we define the user interface and you'll notice that it's created for us a user interface with a search field as well as a table view to display all of the movies that it's found let's clean up some of these names that's the one that bothers me the most because it's got that dot in there let's Center everything that wasn't center there we go and let's run this application so it's building and running the application and what we're going to see is a web page displayed and we'll be able to search and display the information from within the database primarily using the information that was generated and put into that model file so we can search for movies okay i guess i didn't Center that puppy let's go back and center it there we go and let's look for action movies match there are all of our action movies you'll notice that we have the title the category the date released using a date formatter so you can easily format that to whatever displaced ring you wish revenue using a number formatter so you can automatically format that to whatever number format you wish and then traversing the relationship from a movie table over to studios and getting the related studio name and if we type in nothing we should get all of the movies of which we have a number that's an introduction of how you can begin using eof primarily starting by generating a model and then building a simple project to get your feet wet with using the model and seeing how it interacts with the database Thanks that's it for that demo okay so now we've got the introduction out of the way let's talk a little bit about the architecture of eof and how it's doing all that stuff because that does look like there's a lot of heavy lifting being done behind the scenes that obviously I did not have to do in that demo a lot of it does have to do with this configuration on dreis likes to say that you need to spend quality time with your model and that is true because a lot of what eof is doing it is based on what that configured what that model is configured to do how that mapping is configured in the details of that model so let's take a look at this what we call the eof stack starting with a database pre-existing quite often and the model now the model you think if it's so important why isn't in the middle well really the model is configuration information and it's being used as a reference so the rest of the stack knows what to do in fact you could potentially have multiple models each model referring to a different data source so you could have one looking up directory information using jndi and another using jdbc to hit a database I actually might I have an app that does such a thing since you can have multiple models there's a class called the model group which we won't talk about much but its main purpose in life is to manage the fact that there are more than one models potentially that model group is referred to by the object store coordinator and as we'll see as we talk the object store coordinator is you can refer to it as the root object or it's kind of the center of an eof stack it's got some stuff going on above it and some stuff going on below it but it's really doing a lot of the coordination thus its name it's also kind of the choke point for doing things like multi-threading and concurrent access essentially that object store coordinator is the centerpiece of an eof stack now going up the stack because this is the object that as an using eof you will most often interact with is the editing context and the editing context is the go to object if a 0 f or a movie the editing context would be the leading man or woman I don't know which we've never established the gender of the editing context Andre ascending no preference so the editing context is your go-to you ask it to fetch it's the object that you when you create a new enterprise object you insert it into the editing context so it'll be ready to get inserted in the database the next time you tell the editing context to save when you delete an object you have to tell the editing context when you have a bunch of changes and you want to revert them you tell the editing context and whenever you change an enterprise object the enterprise the editing context is observing and so it notices those changes keeps track of that fact so it knows to save those changes to the database so the editing context is really your go-to object in eof now when you do a scan editing context to fetch and that is essentially what we did when we typed in action and hit the submit button the editing context was asked hey go get things that have action as their category coming down the stack the object court in the store coordinator finds out there's a fetch going on on the fly it actually creates these next objects if they weren't there already talked about what they do in a moment then the adapter is what actually talks to the database so let's say that's that fetch category we want action heads all the way down the JDBC adapter is going to generate the sequel that actually gets sent to the database and what it's going to get back are called raw rose they're not fancy they're not Enterprise objects they're just dictionaries full of key value pairs there's nothing particularly special about them they're just raw data containers they also don't take advantage of a lot of nice features and functionality of AOF that happens at the next layer up those raw roads are handed from the adapter layer up to the database layer where a raw row is turned into an EO it's kind of like Pinocchio becoming a real boy that's essentially what it is instead of a wooden raw row you get a full fledged object with an object graph in the light at that time a very specific thing happens a snapshot is taken of that row that snapshot as we'll see in a moment is maintained as a cash that can be used later for things like somebody else shows up on top of the stack and fetches we can reuse that information we can cash so that we're not always hitting the database every single time we need a piece of information will also see that that snapshot is very important when we talk about data freshness which we will do today so that snapshot occurs and at the same time that raw row is turned into an EO an enterprise object of the correct class that you specified in the model is created those the data is populated and you related outlaw we'll get to that in a moment because there's the EO and finally besides that EO any relationships a little object is created called a fault to a little place holder that says well you don't necessarily need the studio right now or you don't necessarily need the list of every time I've logged in that's a related to many array right now just put a little placeholder there when you asked for it I'll go get it then okay I'm going to go forward but I forget that might take me too far yes it did oh and I got to build it again okay quick review as they go by remember what I said everybody with me excellent so looking at this when we talk about advanced topics it's good to have this picture in your head it can be you know you can use circles instead of boxes in your head if you want it's your head but the basic structure should remain the same and the things to think about are the things that you often need to think about our what's going on that relationship between the EO and its snapshots what's going on with these false when are they getting triggered those tend to be very important control points when talking about things like memory management or data freshness of your things that are in your yo F stack now let's talk about a couple of common configurations of Eos the first of which is multiple editing contexts and so in addition to one editing context on top of this stack we can have many and in fact this is the default configuration of a web objects application every user that shows up to the site gets a new session every session has a new default editing context which sits on top of the same object store coordinator what that means is that they all share the same snapshot and so this is where some of that caching comes into play we're just because somebody just showed up to your site doesn't necessarily mean that we have to fetch everything once again for them because a snapshot from somebody else's session might have already grabbed that information and kept it in memory and so we can have that same row in the database have a snapshot for it and have up I'm going to yeah there we go i'm having some clicker problems okay so in this case these EOS could both be the same row underneath in the database but they're in different editing contexts which means that one user can make some edits to it and then decide not to save those edits the other could do the same but underneath both of these eos is a snapshot the other common configuration is potentially using multiple eof stacks now the show these I'm going to compress this diagram into a little more compact model and we'll add two stacks now you say well Wow multiple stacks that sounds kind of out there but really as soon as you launch a second instance of your objects application you have a situation where you have multiple stacks one app has one stack one app has the other stack and as you'll see here they can both deal with the same row from the database but they have a different set of snapshots one stack does not know about the other stack and what essentially defines creating a stack is that object store coordinator that middle center piece okay that said everybody will laugh so let's go back one everybody have that clear in your mind so now we're going to talk about memory management and then a little bit about data freshness so memory management as I looked at this material i realized that i was using eof circa 45 in my head rather than five to three so things to note the editing context is using weak references so only things that it actually needs to hold on to things that are pending inserts deletes or edits or updates need to be retained but the EO itself has a strong reference back to its editing context this has a couple of caveats the first is that if you ask for all the registered objects in an EO it's not particularly useful as some of them may have been garbage collected you can if you want the old behavior set retains registered objects which will do that on the editing context the editing contact subclass shared at it in context always does you share a strong references I should say so faulting I talked a little bit before about that kind of ghost object called a fault what that is in essence is an empty shell of a particular type of object so as this says the size of the fault is the size of the EO essentially created using the constructor but not initialized with values to defer the fetching of that value until you need to access the object but what this means is that when we fetched in that original movie there was a fault of a studio kind of hanging out there taking up as much size as a studio deferred faults allows there's a setting that essentially allows that creation of the fault even to be deferred so that there's this single shared object that's standing in for the fault which is a stand-in for the real object that is more memory efficient so if you are extending EO generic record you'll automatically have deferred faulting otherwise you will want to if you're using EO custom object you will want to override a method which seems have disappeared from the slide just I think something like uses deferred faulting you want to return true to that the men's the reason why I awake from fetch and awake from insertion is up here is that those two methods essentially if you look at the process of creating a fault a constructor is called if you put your initialization logic in that constructor well when that object is finally initialized it's going to pull information up from perhaps a snapshot or the database and all the work you've done might get overridden the appropriate place to put initialization information is by subclassing generic record and then putting it in awake from fetch or awake from insertion some other notes some good tips a blob of data you may want to factor that out into its own table I think the canonical example is an employee and their employee photo if you have some little lap and you're always just searching for first names and email addresses and phone numbers you don't want to have to bring their whole image in because it's part of that row a better thing to do is to have a to one relationship to another table that stores the blob of data so that you only have to access it over a relationship when you need and some blobs might be better just to store them in the file system and store a path to the blob in your database some other optimizations sometimes you never use the too many class property so maybe you know that the employee belongs to a department but in your particular after your department never needs a list of all the employees by turning off that reverse to many it can save that fault from being created and save you some memory also some rarely used attributes like you might have that employee where you're always looking up first name last name email but then they have all this other chunk of data like their social security number and you know all kinds of crazy stuff you might have just the employee and then a join to a table that has a lot more in the other table but that's used more rarely another thing is you can actually hard code a fetch that will do the to many relationship for you so that it's not doing a join you're just using faulting excuse me you're just using a fetch to grab the objects that you need if you're using key value coding write the name of that method you can bind that up as if it's a relationship key value coding won't know how that array was provided it just knows there's a method name that it finds and calls to return that array the shared editing context so the purpose of the shared editing context is if we go back to that picture of the stack in our head is that i mentioned that multiple editing contexts can all deal with the same exact row as a separate EO in each editing context so there's memory used for each EEO in each row excuse me in each editing context a shared editing context allows you to touch things into this shared editing context that conceptually those EOS are part of every other editing context sitting on that eof stack and so the memory is shared not only for the snapshots but also for the EO there are some caveats to using this the first is that with that shared editing context you cannot have any relationships that go out of the EOS in that you can have things that point in but nothing going out otherwise you will hit trouble let's see and you can't use it across stacks right it's sharing the same snapshot and it's only dealing with items that are on the same aof stack which means the same object store coordinator and what if you got tons and tons and tons and tons and tons and tons and tons and tons of Yoos or in tongues well we got a million eo's batching right you want to batch things up there are a few things that you can do one is you could use raw rose because when you're using raw rose it's quicker you're not generating snapshots oreos you're just getting those raw dictionaries back which you can use to display actually they're probably much more handy for display purposes than for edit purposes project wonder also has some nice reusable stuff such as a fetch specification batch iterator which will let you fetch things in by batch and also a way to get an object count with a particular qualifier so it's easy for you to build that user interface that says you know now showing 1 through 10 of 7.2 million because has anybody here ever gone through 1 through 10 all the way up to a million on a website you have that's a lot of time you have on your hands because most users won't go through a million records on a website so often you want to give the impression that you grabbed them all but not do so and then sort of the lowest level you can possibly get is you can actually go down to the very jdbc adapter the JDBC channel and over a ride fetch row which is the kind of atomic method that's touching in every single row from the result set you can override that method call the super so the fetching happens for you and then you do something with the data and return null for the method so eof thinks nothing came back for that row yet you've already grabbed the information done something like aggregated it or something of that nature and you get back all these results and the rest of us thinks you got nothing back it's kind of tricky but it definitely works ok that's some memory management stuff now let's talk about data freshness so data freshness eof is a big big cash so those snapshots are cashing and anytime you have caching no matter the environment you have a data freshness thing to think about so there are a lot of techniques and features within aof that deal with data freshness and keeping your data fresh what I'm going to do now is rather than go through them in slides let's go to a demo let's go to the demo machine let's get rid of this demo boom so one thing I found is that although I have been through what r e faulting is refreshing is invalidating all of these various things that deal with eos that over time as i'm developing with eos their definitions get a little fuzzy in my head especially when i have an app that's running and working and then i have to rethink through everything okay now this one's getting rid of the snapshot what's this doing what i did was i wrote a little apps that i call the freshness explorer it's a web objects app that I think helps to illustrate much more than slides can what's going on with the eof stack wait for this to pop on up can't find server let's see if we do the old oh okay hit it once again great okay since I call the freshness Explorer it's essentially what we're seeing here are two eof stacks each one sitting on top of an object store coordinator then within each stack is an editing contact or to editing context both sitting on top of the same one displaying some pertinent information about the editing context that we'll chat about in a moment the related snapshot if there is any any sequel that that stack had sent to the database in the last transaction and then finally doing a raw raw fetch to get the actual database row that will be talking about so let's fetch into this editing context as well as this editing context and so the first thing to talk about is the idea of reef alting so we have fetched these objects in you'll notice that we have to EOS one in each editing context here's the underlying snapshots which is holding on to this information and since we did a fetch there's a sequel transaction that occurred and here's the database underneath we can do some things to this EO the first thing we'll do is something called reef Alton and the behavior when Yuri fault as you'll see is that item is turned into a false it's a fault the snapshot hangs around and nothing else is affected in any other editing context if we touch the fault no sequel is generated default notices that there's a snapshot and says okay I'll use that information now if I have a pending edit with a fault so instead of Bob Jones let's say we're going to Robert Jones I'll submit but not save that change so that change is hanging out in that enterprise object in the editing context now if I revolt it's turned into a fault i touch the fault notice that resulting loses all of my pending edit so that is the behavior of reef alting you get that behavior by telling an editing context to reef Alton objects and handing it the object you wish to revolt a smarter version of reef alting is called refreshing so let's edit Robert once again and by refreshing actually lift through two things yeah let's do that now if I hit refresh a fault was created and then basically refreshed from the snapshot with the changes applied on top of it the granddaddy of all data freshness things the sledgehammer is invalidate okay somebody likes the sledgehammer analogy so when you invalidate all sorts of things happen this object is turned into a fault the snapshot is discarded all other editing contacts that have that row within it also get turned into a fault and all pending edits are discarded so it's a very very draconian way to refresh things let's fetch things back here's one that I wasn't expecting which is when I reef alt the snapshot hangs around in the thing turns into a fault but notice if I reef alt with 10 AO and one editing context my snapshot disappears this is due to something called snapshot reference counting which happens automatically when noe o is referring to that snapshot it goes away now I knew that in my head and I had always thought of that as a mat of memory management sort of thing okay we don't need it we can get rid of that memory but as I was building that that interaction was not apparent to me until I was playing with this app so that's kind of cool so let's put some things in and talk about a couple of other items let's go to this other stack you'll notice that if I make a change over here like Robert Jones submit that when I save the change I should I just submitted it no sequel got sense the database is the same let's save the change you'll notice that what happens when I save that change is the snapshot gets updated some sequel gets sent so the database row is updated and in addition the other EO is turned into a fault as soon as it gets touched it has the latest values so now we have a data freshness conundrum one stack has made a change and so Robert Jones is here but we still have Bob Jones and as long as I reef alt and touch the fault Andrey fault and touch the fault and refresh and touch the fault i'm not getting Robert Jones so I betch well if I fetch I still don't have Robert Jones when you fetch eof is as I said before a big old cash and it is an aggressive big old cash so when you fetch the main reason it's hitting the database is not because it's concerned about the stuff you already have it's concerned because there might be rose in there that meet the fetch criteria that you haven't already grabbed so anything you already have by default if you have a snapshot it'll say okay I got that I don't have to look at it the key toggle there is on that fetch specification to refresh the reef etched objects so check that off and now we'll get Robert coming in since the snapshot has changed any other eos in other editing contexts are turned into a fault so will touch the fault often using a fetch with refreshing reef fetched objects is the most direct and efficient way to refresh a large amount of items at the same time especially if it's a well known group of data or set of data that you can fit into a qualifier all right so everybody's now Robert Jones yes yes now let's make the eof stack number two let's say it's Robert Cray touch the fault there and so now we have a data freshness issue over here boom boom let's talk about the fetch time stamp which can be a source of confusion sometimes does anybody found it to be a source of confusion at times some nodding heads what's going on with the such time stamp is this when you create an editing context by default a time stamp is put on it that's an hour previous two when it was created so we showed up here and started running this at about 9 15 excuse me at about 1115 and so the time stamp on all of these editing context is it about 10-15 an hour at an hour before this thing was created and that will never ever ever ever change on that editing context unless you change it yourself what this means is that anytime that editing context looks at a snapshot it's going to say or 10 15 if it's later than 10 15 it's fine with me it's fresh enough so you'll notice that here we have a fetch time stamp every time a snapshot is created it gets a time stamp in this case 1119 am so no matter what we do without changing the editing context timestamp things that are fetched in by that editing context are going to have a time stamp later than its time stamp which means that if I reef alt touch the fault REE fault touch the vault I keep using that snapshot one mechanism for data freshness is to update the fetch time stamp in the editing context in this case we'll update it to now now it's 11 24 now 11 24 is later than 11 19 so now if I recall when I touch that fault it's going to notice 1124 is later than 11 19 it will hit the database pull back the freshest values make a new snapshot and there you go ok so what any other items that I wanted to chat about here that's about it let's go back to slides so I intend to have that available I find it oh cool just in building it and playing with it I know I learned some things the other thing is that I think that often we get I'm REE faulting or I'm doing this one thing and we think about it in isolation and what I like about playing with that because that's essentially what we're doing is playing with it is that you see interactions between these different techniques that you may not have noticed or thought about before but they're very obvious to you when you see them graphically so i think i'll be using that a lot now that I've built it great data freshness now since others might slide so since we don't have a kind of a way for that demo to get to everybody else who might not be seeing this session live we're going to have some slides so they'll see it but I'm going to crank through these because we've already talked about most of this stuff in the demo so reef alting again effects that one editing context we saw that it turned into a fault we touch the fault it uses the snapshot if it is fresh enough it doesn't affect any other editing context and there's no database round trip unless for some reason for example that database isn't or that snapshot isn't fresh enough we can't use that existing snapshots invalidating is that sledgehammer approach all editing contacts lose all pending edits the snapshots thrown out and then the database is hit now invalidating is pretty heavy-handed there are some things you can do you can imagine we had one object so okay I have I invalidate and then i touch the fault and then I get one fetch to the database but imagine you know you're displaying that million records well let's say a couple thousand records that you have and you say invalidate all objects now every time you touch one of those objects it's a separate transaction as separate fetch to the date bass by default so get that one you have some repetition you're just playing on a page and it's like it's a database oh I need another one hit the database oh I need another one hit the database oh and it does that thousands of times which is obviously a performance hit one thing that you can do to prevent that is to set batch faulting which is set in that very important model file and the idea behind vets batch faulting is you set a batch number and it's sort of like when you're at home and somebody else is up at the refrigerator while you're watching TV and you say while you're up why don't you get me something too so batch faulting essentially saying why you're going to the database to get one studio you might as well bring back ten or a hundred or whatever would other up whatever number as you go through this seems to make sense for your data set and the size of your data that will definitely increase the performance from manually fetching to restore snapshots using refreshes researched objects is potentially even better because you're not relying on the infrastructure you're specifically saying I want these particular objects that match this particular criteria to get fetched at this particular moment in time return to me and refreshed so that's very precise control and while you're doing that you can use prefetching which our keep as that you specify along with the fetch that say while you're down there get in all these in this case movies bring back the related studio and so you will get not only a fresh version of all the movies but a fresh version of all the related studios all within the same database transaction refresh objects we hit the hit on that briefly it's like reef alt object except it is not going to throw away pending updates or inserts and it will use that existing row snapshot playing with this the behavior is that if there are no changes to the object that you refresh it actually turns it into a fault if you if there are pending changes within the request response loop seems turn it into a fault unfall tit and apply the changes data freshness this is one that again i think is much easier to see the results of it than to explain the results of it but again you make a new editing context it gets a timestamp of an hour ago so you show up at ten am a user does it gets a 9am timestamp it's an absolute time and unless you do something that time stamps never changes anytime a snapshot is created it gets a timestamp those two are compared if the snapshot is too old then that snapshot will not be used the next time that editing context is trying to use it what you might do and what I do in the source code is I just tell that editing context to set its time stamps to something else you know make a new NS timestamp you can do that perhaps when the session wakes up so that every time that user has a new transaction you update the timestamp and that then turns it into more of a rolling window so that every time a transaction occurs and then some faulting occurs you can make sure that it updates and then again the set refreshes reef etched objects and the prefetching now if you want to go just crazy you can go to the EO database which was on our model it's the object that's actually maintaining all of those snapshots and you can mess with them directly so any o global ID for you new folks it's simply an object that is a unique identifier for an enterprise object and it's how you basically map up what snapshots go with what eos for database folks is basically the name of the entity and the prime are you key information don't tell anybody told you cheating at faulting essentially you can record your own snapshots you get the global ID and you say here's the snapshot for that particular object so if you happen to have gotten it from some raw raw fetching or some other means you can just provide it potentially saving a fetch to the database preflighting too many relationships so sometimes you have a new enterprise object and you know a department that's brand new does not have any employees yes eof doesn't know that necessarily there are no employees in the database so if you go to touch that relationship it is going to automatically do a fetch to look for employees you know that there aren't any because you just made the department so you can use this method record snapshot for source global ID to hand it in empty array so that it thinks that it has well it will have a snapshot that says there's nothing related to this therefore it's not going to hit the database if you access the too many arrays of that newly inserted object and if you want to just blow away the snapshot for it too many so that the next time it's accessed it is absolutely positively refreshed you can use that same method and hand in null instead of an array which will get rid of that too many snapshots and so the next time that object with that GID and that relationship name is accessed it will say I don't have a snapshot better go get fresh information from the database again this is very low level stuff more likely you would want to use you say a fetch specification with prefetching necessarily before having the revert to this and then when you're doing this stuff at the EO database level talk about multi-threading in a moment you want to lock and unlock the object store coordinator that multithreading I can't go through all of concurrent programming right now we have only six minutes so there are a lot of good books as we talk I'm assuming that you have some knowledge of concurrent programming in Java and concurrent programming in general there's some good docs on this in the what's new moon with objects 52 dots java apps always multi-threaded here are some examples of multi-threading finalisation timers session timeouts if you do your own threads notifications so you cannot it is impossible to write an eof application that is completely unmarked a threaded which means we need to deal with it use try finally so try to do something like locking a resource will tell you in a moment what you need to lock then in the finally block unlock it so if any problems occur that finally block is always called and you don't deadlock your application essentially if an object in eof or found a web objects foundation does not have a lock on it you need to protect it either the synchronized block or using your own lock or some way of doing it so that's arrays and dictionaries you need to lock those or deal with the concurrent issues yourself for things like get it in context the object store coordinator you can lock those it has the API to do so you can also use trilok on an NS recurring lock or an editing context that you won't blocked as you see is this thing able to lock for me or to somebody else have the lock as you're debugging you can use control / or kill quit with the PID to produce a stack trace by thread as to what's going on and the commercial products optimize it in J probe are also very very handy so as you're using an editing context if you're using a nested editing context you need to lock the nested editing context even though it is using its parents lock you still do need to lock that child editing context these shared editing context locks itself so it's the one exception that proves the rule that that's the one that locks itself everything else you need to do yourself you need to always lock the editing context whenever you're using any of its Enterprise objects in your own code so even if you're doing some read only stuff you still need to lock the EO excuse me lock the editing context do whatever stuff you're doing in code and then unlock this editing context if you're operating at a lower level than your EOS and editing context you'll want to use the lock the object store coordinator instead as we talked about with EO database stuff so that is showing us that that object store coordinator is in essence that root object it is the thing that around which all this locking is based is that object store coordinator so remaining things to be careful of as your bopping around DOF locking around the model Notification Center an entity in web objects they have a method that is allows concurrent requests handling which has nothing whatsoever to do with eos multithreading it has to do with whether webobjects applications are handling incoming requests in a multi-threaded manner that doesn't have anything to do with whether you've turned on multithreading in EOS as we've just said it's always to some degree multi-threaded so some things to watch out for intersecting locks where you need to have this lock and this lock to be able to do something and then release this lock there's more possibility for deadlox keeping things as dead awful simple as possible to solve the problem is the best bet when you synchronize some methods they're not just fancy keywords if there's an object lock going on there and so when you're in a synchronized block and then you lock something else or do a blocking operation nothing else is able to get into the synchronized block or that object any synchronized method of that object until that code is released so try to keep your blocking code locked by out of the synchronize blocks but possibly using wait and notify or recursive locks concurrent database access so this is pretty fun concurrent database access the general idea is you have multiple eof stacks each stack again with an object store coordinator of its own is able to have concurrent access to the database so you want two things hit in the database make two stacks that's the takeaway basically each of those stacks has its own set of locks database channel snapshot cash since you do potentially have the overhead of multiple snapshots for each of those this is especially handy if you're fetching raw rows because there's no overhead with snapshots or EOS or notifications going on you're just getting back an array of dictionaries that you can do with what you will which can be very handy if potentially you're doing an app were you doing a lot of fetching in and displaying of stuff potentially with a little less editing going on and to make one is dirt simple you make an object store coordinator that takes no arguments and at that point you've just made kind of a basis of a new eof stack then make a new editing context and hand in that object store coordinator as the argument to the constructor and then start using that editing context all of the objects beneath the scenes that are doing the sequel generation that like are created for you automatically the first time you touch the database I mentioned raw rose already and the actual concurrent seeds should be noted depends on how you have your database configured sometimes it's a configuration issue with the database sometimes it's a money issue with the database where you can only have so many connections because of your license but times the reason why you might not be seeing concurrency is that you haven't configured the database right or you haven't paid the database company enough money ok so we've reviewed some basics some memory management data freshness multi-threading and concurrent database access for more info there's documentation up on in the reference library there's who to contact andreas Bob Katherine wins an enterprise-level webobjects support and consulting I don't see anybody jotting down so i'll go on the reference library and now let's have some folks up for Q&A thank you [Applause]