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]