2007-03-13
Version 10, changed by jaredj 03/14/2007.
Show version history
Agenda Item 1: Status on outcome of last week's meeting.
Quick status on implementation of filtering APIS. (Jared Jurkiewicz)
Quick note: #2544, #2545, #2541, #2546 have prototype resolutions that have been provided to the community for review
What needs to be done to get the prototype code checked in? (Douglas Hays wants to see this code go in, as he needs the filtering capability for work being done in Dijit (the ComboBox? and so on)Provide fully updated files to a committer? (This has been done)Provide just a patch to the committer?Attach the fully updated files or a patch to the tracker?
Result: Send it to Brian Skinner for review and commit.
one last naming thing:
- lack of parallel structure between onBegin and onCompleted (present tense vs. past tense) -- should it be onComplete instead, or onEnd?
- instead of "saveResult", would it be better to have "onCompleteArray"?
Agenda Item 2: Additions to filtering capability to simple filtering API (Filtering api as discussed from 2007-03-06):
Item 1:One
thing I would like to propose we add here is the support for the ?
single character pattern match in addition to the basic * pattern
match. There are three reasons I'd like to add this with community
agreement as a standard option on the API:
- It should be less code in the simple pattern generator to
support this than to ignore it (about two lines less, I believe). So,
we get it virtually for free by deleting two lines in the Filter helper that many datastores can use.
- There is a
definite way this can be mapped to relational stores like SQL. In SQL,
as * is to %, ? is to _. So, there should be an easy translation to
backend stores that use DB queries.
- One of the widget contributors would like to see this added (Douglas Hays).
Item 2:
Support
for non-string (numeric) pattern matching. While going through this, I
realized another likely common fuzzy search people may wish to do
involves numbers, such as X >=5. This can come into play where you
want to search for all items that have a last modified date greater
than some value, for example. How should this be done, if any?
One way is to have the ability to
specify a numeric comparator, in addition to the basic string comparators such as:
'=<some number>'
'>=<some number>'
'<=<some number>'
'><some number>'
'<<some number>'
'!=<some number>'
Another is not to have this on the standard API at all to keep it simpler and let individual datastores implement this however they wish to implement it. Chris M is in favor of leaving it up to the datastores and keep the required API of the datastore as small and simple as possible.
CCM: More specifically, we should not be introducing expressions other than simple wildcarding for string values into param values for find(). We stated in previous design discussions that the actual query language used in datastores is the responsibility of the datastore and must be hidden from the client of the find() api. The find() function is only provided to allow parameters to be provided for substitution into underlying datastore query language expressions. Exposing expressions through the api goes directly against design decision to shield the client from the language.
Agenda Item 3: The Write API
- 'Write' defines a method to set an item attribute value as set(), while Read.get() has been renamed to Read.getValue(). Shouldn't Write.set() be also renamed to setValue() for symmetric set of APIs? (skinner: yes, let's change it to setValue())
- What should save() method take as a parameter? what should save() return? (especially, to support async.). Currently in the API docs it states:
* ISSUE -
* Should the async save take a callback, like this:
* store.save({sync: false, onComplete: callback});
* Or should the async save return a Deferred, like this:
* var deferred = store.save({sync: false});
* deferred.addCallbacks(successCallback, errorCallback);
* Or should save() return boolean, like this:
* var success = store.save();
This needs to be decided on.
JaredJ: For symmetry of the read/write APIs, my vote would be for the store.save({sync: false, onComplete: callback}); Use callbacks, the same as you do for the find API. It also allows you to easily specify other callbaclk, such as onError. I don't see what functionality a 'Deferred' object gives you that could not be done with using the callbacks method.
skinner: It would be good if the dojo.data APIs did not have any dependency on dojo.Deferred. If we can keep the APIs independent of any dependency on the dojo toolkit then people who don't use dojo can still conform to the APIs, and then we can play nicely with other toolkits. So, +1 for just using callbacks, like onError.
- From looking at the APIs as they are today, Write.save() seems to assume that a data store tracks changes to items to be wrote back to the server on save(). Is this the intention? (skinner: Yes, we also have write.revert and write.isDirty, which implies that the data store must track changes.)
- An explicit method to just save a single item would be convenient to have, such as:
var item = store.newItem(...);
store.setValue(item, "anAttribute", aValue);
...
store.saveItem(item);
may look more intuitive, compared to:
var item = store.newItem(...);
store.setValue(item, "anAttribute", aValue);
...
store.save();
where the caller may not 100% sure on what will be saved, especially when multiple and complicated calls to newItem(), setValue() and deleteItem() are involved.
saveItem() also allows a data store to skip the task to find out what to save by examining records of "new", "modified", and "deleted" items.
Minutes:[5:52] * dmachi (n=dmachi@pool-72-66-189-43.ronkva.east.verizon.net) has joined #dojo-meeting
[5:53] * ChanServ sets mode +o dmachi
[19:56] * ccmitchell (i=jaxspher@nat/ibm/x-42604487102b3934) has joined #dojo-meeting
[19:59] * jared_j (i=chatzill@nat/ibm/x-734ae8b1a691015a) has joined #dojo-meeting
[20:01] * brian_skinner (n=brian_sk@adsl-68-122-193-57.dsl.pltn13.pacbell.net) has joined #dojo-meeting
[20:01] <brian_skinner> hi
[20:01] <ccmitchell> hola
[20:01] <jared_j> Afternoon. do we want to wait a few mintes to give people time to join?
[20:01] * slightlyoff (n=alex@204.14.154.182) has joined #dojo-meeting
[20:01] * ChanServ sets mode +o slightlyoff
[20:01] <brian_skinner> yup
[20:02] <ccmitchell> why don't we start with the commit issues...
[20:02] <slightlyoff> is the agenda in the topic?
[20:02] <ccmitchell> n
[20:02] <brian_skinner> agenda: http://dojo.jot.com/2007-03-13
[20:03] <slightlyoff> gratsi
[20:03] * slightlyoff changes topic to 'http://dojo.jot.com/2007-03-13'
[20:04] * ttrenka (n=ttrenka@c-24-131-182-228.hsd1.ma.comcast.net) has joined #dojo-meeting
[20:05] <ccmitchell> hi tom
[20:05] <ttrenka> hi
[20:05] <ttrenka> again I have to lurk mostly
[20:05] <jared_j> All right, it's 3 minutes after and the major folks are here ... so lets get rolling and see what we get to.
[20:05] <ttrenka> sorry about that.
[20:06] <brian_skinner> sounds like Douglas Hays is eager to get the latest code into trunk
[20:06] <brian_skinner> sorry, i didn't realize anybody was waiting on that
[20:06] <brian_skinner>
in Jared's last mail to me, he said he hadn't gotten as far as he
wanted to, so I thought the last round of code was an interim work, not
necessarily ready
[20:06] <brian_skinner>
and he mentioned that he was planning to send mail to the contributors
list about some of the design, listing pros and cons, and soliciting
feedback on it
[20:07] <brian_skinner> so i had thought i should maybe wait on that before doing a checkin
[20:07] <jared_j>
First thing I want to do is just give a quick status. I've sent Brian
(and the contrib list), a curerent prototype set of files I'e chanegd
on where things are at. They provide basic implementations of fetch()
and the filtering, plugged into the JsonItemStore. This morning I've
been working on sort, and I thinmk I about have it sorted out too,
which a ncie little reusable Sorter many...
[20:07] <jared_j> ...datastores can make use of (based off Tom Trenka's filtering table code).
[20:08] <brian_skinner> cool
[20:08] <jared_j>
I'll be sending that out to Brain Skinner either tonight or tomorrow
morning, which exanded testcases for JsonItemStore (to test the sort),
plus a few standalones for the Sorter and Filter helpers the datastore
imples can use.
[20:08] <jared_j> Er, expanded.
[20:09] <jared_j>
I also fixed a couple of the trackers Brian noted last week. Namely
throwing errors in indentity collision, and the problem of calling
getByIdentity() failing if called before a find.
[20:09] <brian_skinner> i think i somehow missed the mail where you sent the prototype to the contributors list -- when was that?
[20:10] <ccmitchell> i think it might be pending...waiting approval (file size)
[20:10] <jared_j> Yeah, it was 10K over the 40K limit.
[20:10] <slightlyoff> ccmitchell: I'll do that right now
[20:10] <brian_skinner> thanks slightlyoff
[20:10] <jared_j> I sent slightlyoff an e-mail about that yesterday. :)
[20:10] <slightlyoff> jared_j: sorry, took yesterday off....family stuff
[20:11] <jared_j> slightlyoff: No big deal.
[20:11] <jared_j> I've also been trying to stub out a dojo.data work plan to help give you an idea on what will try to drop when: http://dojo.jot.com/WikiHome/Dojo%20Work%20Schedule
[20:12] <ccmitchell> are all the code/api's doc'd in the latest drop?
[20:12] <jared_j>
The name suchs, it's really under dojo.data. I'll be changing that when
I get a chance (and try to move some of this stuff to drupal)
[20:12] <jared_j> The zip I send out tonight or tomorrow should be doc'ed (API docs), unless I've missed one.
[20:13] <jared_j> I do need to get access to the drupal site so I can start updating the book as well as the porting guide.
[20:13] <slightlyoff> jared_j: who sent the zip?
[20:13] <slightlyoff> (trying to find it in the admin UI)
[20:13] <jared_j> jared.jurkiewicz@gmail.com
[20:13] <slightlyoff> thanks
[20:14] <ccmitchell> jared, i thought the XmlStore would drop in M2, not M1
[20:14] * peller (n=peller@216-15-119-69.c3-0.nwt-ubr2.sbo-nwt.ma.cable.rcn.com) has joined #dojo-meeting
[20:14] <jared_j> We originally said M1 when we talked yesterday. I can move it to M2 if you want.
[20:14] <slightlyoff> it went through
[20:14] <slightlyoff> jared_j, ccmitchell, do you guys have a work plan and a timeline?
[20:14] <slightlyoff> I'd like to get your benchmarks on the project plan
[20:14] <ccmitchell> i think it should move to m2 (even though it's getting developed during M1)
[20:14] <jared_j> slightlyoff: http://dojo.jot.com/WikiHome/Dojo%20Work%20Schedule
[20:16] <slightlyoff> jared_j: thanks
[20:16] <jared_j> Updated plan, moved XmlStore to M2.
[20:18] <brian_skinner>
the schedule looks great -- i have a couple questions about stuff in
milestone 2, but maybe we want to wait until milestone 2 to talk about
that
[20:18] <ccmitchell>
so M1 is API's plus JSONItemStore. All other DS impls go to dojox for
now. In M2, we have an XMLItemStore impl that can be provided in either
dojo or dojox (prefer dojo)
[20:18] <jared_j> And updating estimates a bit. Some things took a lot less time than I thought. :)
[20:18] <jared_j> brian_skinner: Which items in M2, just for my curiousity?
[20:19] <brian_skinner>
two things -- one is that i think we may want to do update
notifications without using topics, or at least explore that idea,
whereas the current outline assumes that we will use topics
[20:20] <brian_skinner> and i think we might want to define the notification API before thinking about binding
[20:20] <ccmitchell>
slightlyoff: in your work plan, it currently goes out 1-1/2 milestones.
Will there be two or three milstones leading up to RC1?
[20:20] <ccmitchell> we can work on notification api next
[20:20] <slightlyoff> http://trac.dojotoolkit.org/roadmap
[20:21] <ccmitchell> also need the child referencing in discussed (binding tree to ds)
[20:21] <jared_j>
brian_skinner: Ok. Will keep those in mind. The notifications API
hasn't really been defined out much at all yet, but needs to be.
[20:21] <slightlyoff> ccmitchell: right now it's M1, M2, Beta, etc.
[20:21] <slightlyoff> ccmitchell: but it's straight beta - > RC
[20:21] <ccmitchell> is beta a timeperiod, or a point in time at end of M2?
[20:22] <slightlyoff> beta is a time period
[20:22] <ccmitchell> k
[20:22] <peller>
brian_skinner: ttrenka has suggested that notification APIs are
relevant, even required for grid, so yeah, I think moving it up sounds
good
[20:22] <slightlyoff> ccmitchell: there's no RC time scheduled right now
[20:22] <slightlyoff> ccmitchell: but there's a bit of play out toward the 0.9 final date
[20:22] <ccmitchell> we started discussion of notification 2 meetings ago. need to revisit
[20:23] <ccmitchell> are we done with Item 1?
[20:23] <brian_skinner> ccmitchell: not quite
[20:24] <brian_skinner> two questions
[20:24] <brian_skinner> one for slightlyoff
[20:24] <slightlyoff> ok
[20:24] <brian_skinner>
is it okay if jared_j just sends me files, and i check them in -- or do
we need to go through a process of jared_j making patch files and
attaching them to the trac ticket?
[20:25] <slightlyoff> brian_skinner: you can just check 'em in
[20:25] <brian_skinner> cool
[20:25] <slightlyoff> brian_skinner: but when this gets moved to core, we'll enforce the ticket thing
[20:25] <jared_j> Ok, I could do either. I just wanted to follow your process.
[20:25] <brian_skinner> okay
[20:26] <jared_j> I see you added two items to #1, Brian.
[20:26] <brian_skinner>
and then one question for jared_j -- i'm excited about all of the new
code, except for the part about the LRU cache, which i think may be
problematic, and may not be a big win -- would it be okay with you if I
checked in everything else, but left out the LRU cache feature?
[20:27] <brian_skinner> or, left it out at least until we can discuss it more
[20:27] * slightlyoff envisions research papers being written about optimal caching strategies in dojo.data providers
[20:27] <jared_j>
I, or you, would have to reqork the fetch() impl on the base Result if
you want to do that. We are going to need caching of somesort for
either Datastores to use or the result to use.
[20:28] <jared_j> If you really want, I can yank it out for now and redo result to always just call to the DS in some mannter.
[20:29] <brian_skinner>
jared_j: i think letting the DS have all the smarts about caching is
the way to go, leaving the result object as simple as possible
[20:29] <jared_j>
That then puts all the onus of caching on the Datastore itself (which
is fine). In addition to pcotentially providing a better fetch() impl
for the result (that's tuned to how that DS can optimally page)
[20:29] <jared_j>
I'm fine with that, really. I think the SimpleLru is decent for most
Dses to use as its own caching mechanism if they way too.
[20:29] <jared_j> but we can discuss that. I tried to just come up with something generally reusable.
[20:30] <brian_skinner> okay
[20:30] <jared_j>
Removing result caching *does* mean the Datastore had better provide a
better fetch() imp onto the result.js when it builds the object; the
brute force method is horribly slow for large item sizes.
[20:31] <jared_j>
Result does have to provide some sort fo fetch impl, and the only way
with the current Read.js apis is not efficient.
[20:31] <brian_skinner> yes, i don't think we offer the brute force code at all
[20:31] <jared_j> We need to.
[20:31] <jared_j> We don't state Datastores have to implement a fetch()
[20:32] <jared_j> IT's not on Read.js. And Datastores don't 'implement' the result interface, really. They return instances.
[20:32] <jared_j> Well, unless you'reokay with Result.js returning an unimplemented function that all Dses have to provide.
[20:32] <brian_skinner>
i don't think we need to require that all datastores implement a
fetch() -- but we can say that if a datastore wants to use the
off-the-shelf result object, then it has to implement a _fetch() method
[20:33] <jared_j>
I was just figuring haveing a bruteforce version made it such that a
lazy DS writer wouldn't have to implement it if they really don't want
to.
[20:33] <jared_j> The btude-force fetch, once you stip out the LRU stuff, isn't that much code, really.
[20:33] <jared_j> Er, brute
[20:34] <jared_j> What are other folks' take? I'll bow to majority opinion. :)
[20:34] <brian_skinner>
good point -- if the brute force method is only a few lines of code,
then maybe it's not a big deal to leave it in
[20:34] <jared_j> All the brute force does:
[20:35] <jared_j>
calls a new find with a specified out of (start + count), then subsets
the return to the chunk desired and returns that.
[20:35] <jared_j> So, if you're talking 1 million items...
[20:35] <jared_j> It's going to seriously suck.
[20:35] <jared_j> You're talking small store, eh, not a big deal.
[20:37] <ccmitchell>
just as long as we dont optimize for the million record case, and suck
memory for the 10 item td/tr inline data cases
[20:37] <brian_skinner>
right, and million item stores are the exception, not the norm, so it's
fine to require people to write more code to support their million item
store, whereas it'd be nice to make it as easy as possible to write the
simple datastores
[20:37] <jared_j>
Anyway, I'll look at the code size that ends up being. Looking at it
nwo with witespace. Total of 30 lines of code. (It has to define the
new onComplete functions and such for the find), to give a brute force
basic fetch tha could be over-ridden)
[20:38] <ccmitchell> whats the tradeoff we're talking about here? 5 lines vs 30?
[20:38] <jared_j> That's why I thought having a basic impl people could just use was a good idea. :)
[20:38] <jared_j> Stubbed out no-op function (unimplemented) adds 5 lines. Full brute-force imple adds 30 or so.
[20:38] <brian_skinner> jared_j: yup, point taken -- i was more questioning whether it belonged on result vs. datastore
[20:38] <jared_j> Roughly.
[20:39] <ccmitchell> can one of the js gurus take a look at the lru and see if it can be further reduced to 5-10lines? :)
[20:39] <jared_j> For small stores you don't even really need the Lru
[20:39] <brian_skinner>
ccmitchell: i think there's another issue with the idea of the
result-object LRU cache, independent of lines of code
[20:40] <ccmitchell> even better, optional require
[20:40] <jared_j> More complex stores, or remote stores, will likely need it.
[20:40] <brian_skinner>
trying to do a cache in the result object means that you're really
caching "item handles", not items, which is going to cause problems
[20:41] <jared_j> I'm fine with just saying all caching occurs in the Datastore.
[20:41] <jared_j> And not on result.
[20:41] <brian_skinner> +1
[20:41] <jared_j> The SimpleLru code could still be used in the datastores. :)
[20:41] <ccmitchell> and make lru impl optional require?
[20:42] <brian_skinner> jared_j: yup
[20:42] <jared_j> And after some thought here ... if both the result and the DS cached...
[20:42] <jared_j> You could end up with some weird inconsistancies, possibly.
[20:42] <brian_skinner>
ccmitchell: leave it up to the datastore author to decide if they want
to use the LRU impl, but provide it as an available resource
[20:42] <jared_j> So localizing it to ONE place in the chain == good idea.
[20:43] <ccmitchell> +12
[20:43] <ccmitchell> er 1
[20:43] <ccmitchell> agree
[20:43] <jared_j> I'm cool with that. I'll decouple it from Result before I send you the latest batch, Brian.
[20:43] <brian_skinner> cool, thanks
[20:43] <jared_j> That'll shrink result a fair bit.
[20:44] <jared_j> With regards to Sort, just so people know....
[20:46] <jared_j>
I created a class called Sorter. Without comments, it's really small.
It uses the concepts from Trenka's Filtering table sort, but lets you
do things like addComparator("attrName", function), where the DataStore
can add in your own special comparator functions for partilar
attributes of its items. It has a generic comparator which just does
<> like in Trenka's Filtering and works great...
[20:46] <jared_j>
...for string, date, int, etc. But if you had attributes that were say
other JS objects ... the DS now has a way to tell the sorter how to
compare em.
[20:46] <slightlyoff> hrm, why a class?
[20:46] <slightlyoff> why not a just a comparator function registered in a map someplace?
[20:46] <jared_j> Well, so the datastore can instantiate it for itself.
[20:47] <slightlyoff> yeah, but *why*
[20:47] <slightlyoff> JS's sort() method takes a function
[20:48] <jared_j>
I was trying ti encapsulate the logic so it woudl be easy to use in in
a datastore impl and not cause a lot of line-adds to the DS impl.
[20:48] <jared_j> Basically it encapsulates the function map and method to generate the chain of sort functions.
[20:49] <ccmitchell>
jaredj, to clarify, its not just a single sort() function, but
potentially a set of sort functions in order to do sort by more than
one field, primary, secondary, etc. right?
[20:49] <jared_j> Bingo.
[20:49] <ccmitchell> and the datatype of the props being sorted can vary (number, string, enum), etc.
[20:49] <jared_j> Sort on attribute A, ascending, then on attrbute B, descendting, then on Attribute C...
[20:50] <jared_j>
The wat Filtering table sorts is it builds up a meta sort function that
contains an array of sorting functions that get applied to the items in
trun.
[20:50] <jared_j> Er, way
[20:50] <jared_j> I mimiced that and tried to encapsulate all that chaining into just one call for the DS.
[20:51] <slightlyoff>
ccmitchell: right, but again, why is that a class and why is that state
being kept in an external sorter that then has to know about the table
structure?
[20:52] <slightlyoff> that's lame
[20:52] <jared_j>
To provide something reusable by multiple Datastore implementations and
get the same behavior. Otherwise each Datastore would have to implement
a lot more. Or at least it seemed to me.
[20:52] <slightlyoff> can't you just have a default sort map?
[20:52] <slightlyoff> and have folks plug sorters into that?
[20:52] <slightlyoff> so the datatype name gets sorted that way across all dojo.data users of the same type
[20:53] <slightlyoff> w/o manual wiring
[20:53] <jared_j> That's what addComparator() does on the class. Theer is a default basic sorter you get when you instantiate it.
[20:53] <slightlyoff> ok, great, then lets just jettison the class baggage and call it done = )
[20:53] <ttrenka>
i'm not really paying attention but I should mention that the way the
sorter is intended to work with Filtering is that is never sorts the
underlying data store
[20:53] <slightlyoff> OO will not save us ;-)
[20:54] <brian_skinner>
just out of curiousity -- i think the FilteringTable sort assumed
strongly typed columns, whereas that's not a feature we've provided yet
in the dojo.data APIs, so right now attribute values could be of any
type, which makes sorting them more complicated -- was that a problem,
supporting loosely-typed sorting?
[20:54] <ttrenka> no
[20:54] <ttrenka> in the end it uses the default Array.sort
[20:54] <ttrenka> so if there's no defined type, it assumes string
[20:54] <jared_j>
I can probably revery it back to just a helper function you can call
and pass ti a parameter map of functions to use.
[20:55] <ccmitchell> this code that jared wrote does the same think filtertable did
[20:55] <ccmitchell> only diff is he provided a wrapper around the map of comparitors to encapsulate the function
[20:55] <slightlyoff> ccmitchell: yeah, that's the stylistic thing I'm hung up on = )
[20:55] <ccmitchell> yep
[20:55] <slightlyoff> ccmitchell: it's not idiomatic JS
[20:56] <jared_j> With some small tweaks to the createSoter code, but yes. Similar.
[20:56] <jared_j> I could probably make it work the same by doing....
[20:56] <slightlyoff> it's a good design
[20:56] <slightlyoff> I just want to make sure we're giving Dojo users a consistent experience
[20:56] <ccmitchell> np
[20:56] <jared_j> dojo.data.util.sort = function(sortData, items, store, comparatorMap).
[20:57] <jared_j>
Instead of the class, and the DS just passes the comparator map
(attribute to comparison function), to the build of the chained
comparision
[20:57] <jared_j> That's actually the first way i started it, then thought making it mroe encapsulated would be better.
[20:57] <slightlyoff> wait, will there ever be multiple comparator maps?
[20:58] <jared_j> Apparently I was wrong. :)
[20:58] <slightlyoff> and if so, why?
[20:58] <slightlyoff> and if not, why would we ever have to pass it around?
[20:58] <slightlyoff> (since it would then have a stable location in the object tree)
[20:58] <jared_j> Each Datastore may have a different set of comparators.
[20:58] <jared_j> Or maybe I'm missing something in what you're trying to say (highly possible)
[20:59] <brian_skinner>
don't we really want different comparators for each datatype, rather
than different comparators for each attribute?
[20:59] <ccmitchell> even for a single ds, cant the set of comparators be different across find()'s
[20:59] <jared_j> ccmitchell: We have no way of defining that.
[21:00] <jared_j> On find
[21:00] <jared_j> Publically, anyway.
[21:00] <jared_j> brian_skinner: How do you determine the type of an anonumoys JavaScipt object? It's just 'object' yeah? :)
[21:00] <jared_j> Er, anonymous
[21:01] <brian_skinner> jared_j: right, anonymous objects have no type
[21:01] <slightlyoff> wait, wait, *why* would we want that?
[21:01] <slightlyoff> why would giving different datastores different comparators be a good thing?
[21:01] <jared_j>
What if you have an attribute on an item called 'person', which is a
javascript object containing various things. What if you explicitly
wanted to sort the 'person' field based on some value contained in the
JS object?
[21:02] <jared_j> It allows the datastore to control what sorting on an attribute means.
[21:03] <slightlyoff> I'm very concerned that it's flexbility that no one will ever want
[21:03] <jared_j> Example: You have itels in a JsonItemStore that look like:
[21:03] <jared_j> {uniqueId: 4, person:{firstName:"Linda", lastName:"Lee"}}
[21:03] <ccmitchell>
there should be a basic set of datatype comaparators, number, string,
bool, but there's also enum types thate will need to be compared
[21:03] <jared_j> You want to sort on 'person'.
[21:03] <brian_skinner> jared_j: i believe we should *not* have content that looks like that
[21:03] <peller> unfortunately, it sounds like a very common db/oo thing to do. doesn't mean we have to support it though :)
[21:04] <brian_skinner> we should instead have a reference to another item
[21:04] <ccmitchell> sorting bugs by status (Open, closed, deferred)... how?
[21:04] <ccmitchell> custom
[21:05] <brian_skinner> ccmitchell: yup, custom sorting for custom data types (including enums)
[21:05] <jared_j>
My first iteration of the sort() didn't allow custom comparators.
ccmitchell and peller both got on me about that.
[21:05] <peller> just thought aloud about it :)
[21:05] <ccmitchell> enums are very common
[21:05] <jared_j> So I added a hook to let datastores define a comparator if they wanted to.
[21:05] <slightlyoff> ok, well, my preferred design for this would then be:
[21:06] <peller>
more specifically, a type system like ttrenka has in his table, but
that might be limited to the user (i.e. within the grid)
[21:06] <slightlyoff> 1.) a global comparator object that gets used as the default type reference
[21:06] <slightlyoff> 2.) a datastore property w/ the same name that provides local over-rides
[21:06] <slightlyoff> 3.) *perhaps* a get/set API for these (but that's a big "if")
[21:06] <slightlyoff> datastores then look up this chain to find a specific type sort
[21:07] <jared_j> get/set was only intended for use by the Datastore itself.
[21:07] <jared_j> Not externals, so if it was broken out they're probably not needed.
[21:07] <slightlyoff> get/set is usually cruft in JS
[21:07] <slightlyoff> unless you can make a case that others need to be able to listen for it
[21:07] <slightlyoff> but that seems dubious in this case
[21:07] <jared_j> You don't.
[21:08] <slightlyoff> JavaScript: the language that turns your strengths into weaknesses ;-)
[21:08] <jared_j> I was just using it as encapsulation, is all.
[21:08] <slightlyoff> yeah, ditch 'em
[21:08] <slightlyoff> so then, in your sort method, you'll have something like:
[21:09] <slightlyoff> var comparator = this.comparators[type]||dojo.data.comparators[type]||dojo.data.comparators.default;
[21:09] <jared_j> Right.
[21:09] <slightlyoff> and then we can all go get a beer and call it done = )
[21:10] <jared_j> What do we do about anonymous objects? (As sucky as they are). :)
[21:10] <slightlyoff> test them for a "compare" function?
[21:10] <slightlyoff> and if they don't have one, use the default
[21:10] <jared_j> Fair enough.
[21:10] <slightlyoff> I think the best we can do here is to create a convention
[21:10] <brian_skinner>
jared_j: i think we should say that store.getValue() should never
return an anonymous object -- it should return either an item or a
literal
[21:12] <ccmitchell> reference in via different api
[21:12] <jared_j> So, either an atomic type or a reference to some other thing?
[21:13] <brian_skinner> jared_j: yup
[21:13] <brian_skinner> ccmitchell: i didn't follow that -- can you re-phrase?
[21:13] <jared_j> So ... how do you know it's a reference? :)
[21:13] <brian_skinner> store.isItem(foo) == true
[21:13] <ccmitchell> let's not go there right now :) referencing in child collections/object
[21:13] <jared_j> Ok.
[21:13] <brian_skinner> okay
[21:14] <jared_j>
I'll drop back down to functions for the sort and see if I can get the
comparator map chaining set up as per what slightlyoff wants.
[21:14] <brian_skinner> great, thanks
[21:15] <ccmitchell> Item 2.1?
[21:15] <brian_skinner> agenda item 1, last bullet point?
[21:15] <brian_skinner> or should that come later?
[21:15] <ccmitchell> oops, had to refresh :)
[21:16] <ccmitchell> naming issue, right?
[21:16] <brian_skinner> we can move it down -- i maybe jumped the queue by adding it there
[21:16] <brian_skinner> yup
[21:16] <jared_j> Change the names again? I'm fine with chaning onCompleted to onComplete
[21:16] <jared_j> The other one, not so sure about.
[21:16] <brian_skinner> i'm proposing either onComplete or onEnd -- no preference
[21:17] <ccmitchell> onComplete
[21:17] <brian_skinner> it just bugged me that onCompleted was past-tense, while nothing else was
[21:17] <jared_j> Fine by me.
[21:17] <brian_skinner> onComplete, going once...
[21:17] <brian_skinner> twice...
[21:17] <slightlyoff> sold!
[21:17] <brian_skinner> okay next point
[21:18] <brian_skinner> i think our saveResults thing is overly complicated
[21:18] <brian_skinner> here's how you would use it as defined now...
[21:18] <brian_skinner> result.fetch({onComplete:callback, saveResult:true})
[21:18] <brian_skinner> function callback(result) {var arrayOfItems = result.items; for(i=0; i<arrayOfItems.length;i++)...
[21:18] <brian_skinner> ...
[21:18] <brian_skinner> here's what i'm proposing instead
[21:18] <brian_skinner> result.fetch({onCompleteArray:callback})
[21:19] <brian_skinner> function callback(arrayOfItems) {for(i=0; i<arrayOfItems .length;i++)...
[21:19] <brian_skinner> ...
[21:19] <jared_j> No storing of the items as an array on the result?
[21:19] <brian_skinner> nope
[21:19] <brian_skinner> unless i'm missing some reason to want to do that
[21:20] <jared_j> I'm not aware of the history as to why it was defined that wat in the first place. ccmitchell?
[21:21] <ccmitchell> i'm here... thinking...
[21:21] <brian_skinner> i think maybe it made more sense back in the day where find() was sync by default
[21:21] <brian_skinner> so people could easily just call find() and get an array back
[21:22] <brian_skinner> without ever having to provide a callback at all
[21:22] <jared_j> Well, yes, if you just wanted to return a result object then pull things off it.
[21:22] <brian_skinner> cause everybody knows how to loop through an array
[21:22] <ccmitchell> i think you're right brian.
[21:22] <brian_skinner> but now we're talking about dropping sync access entirely
[21:23] <brian_skinner>
although we may have lost Brad by dropping sync access -- he's no
longer using dojo.data in the Dojo Offline Toolkit
[21:23] <brian_skinner> callbacks == too complicated
[21:23] <ccmitchell> onItemsComplete() ??
[21:23] <slightlyoff> brian_skinner: did he say why?
[21:24] <slightlyoff> brian_skinner: hrm
[21:24] <slightlyoff> brian_skinner: that's....odd
[21:24] <brian_skinner> slightlyoff: i want to try to win him back
[21:25] <brian_skinner>
slightlyoff: He said: "Everything is synchronous, since synchronous
method calls are much easier for programmers to deal with than
asychronous ones, and my underlying operations are synchronous."
[21:25] <peller> everything local is synchronous, yes.
[21:25] <peller> he's the odd case, unfortunately
[21:26] <slightlyoff> I just don't know that it's going to be tennable...esp in his case
[21:26] <slightlyoff> (everything being sync)
[21:26] <brian_skinner>
peller: yes, any underlying operation that's local will probably be
synchronous -- although in dojo.data we're now saying we'll only
provide async access to the underlying sync operation
[21:27] <slightlyoff> I think it's better for us to provide the right API, lets worry about brad after that
[21:27] <brian_skinner> okay
[21:27] <ccmitchell> and make sure async casse is as simple as possible
[21:27] <slightlyoff> yep
[21:27] <peller> brian_skinner: for good reason. we're trying to optimize around the common usage
[21:27] <slightlyoff> 'cause I fully expect he's going to hit a wall on sync usage
[21:28] <peller>
slightlyoff: yes, there are performance issues to be had even talking
to the flash player. we submitted a performance patch related to this
[21:28] <ccmitchell> start having local db queries that take a while... ui thread locked up
[21:28] <slightlyoff> he's dealing w/ "sync-ish" substrates...I think we'll win by being more consistent and straightforward
[21:28] <slightlyoff> so lets get back to it = )
[21:28] <slightlyoff> we only have 30 minutes
[21:28] <brian_skinner> okay, so continue down the all async route for now?
[21:28] <slightlyoff> yes
[21:29] <slightlyoff> I don't see how we can make things perform otherwise
[21:29] <jared_j> Okay, I'll need to pull the sync param off the Read.js interface, then. :)
[21:29] <ccmitchell> so brian, i just dont like the term array
[21:29] <jared_j> So, good to know.
[21:29] <brian_skinner> jared_j: cool, thanks
[21:29] <ccmitchell> in your example
[21:29] <brian_skinner> ccmitchell: i'm open to a different name
[21:29] <ccmitchell> something like onItemsComplete or onItemsReceived...
[21:30] <ccmitchell> not received...to errorprone for typos
[21:30] <brian_skinner> but why don't you like array -- i feel like it helps describe what feature we're providing?
[21:30] <jared_j> I don't like onItemsRecieved.
[21:30] <jared_j> For exactly the typo reason. :)
[21:30] <ccmitchell> onItemsReady
[21:31] <brian_skinner>
if we offer both "onComplete" and "onItemsComplete", I don't think it's
obvious how they differ -- they both get called only after all the
onItem calls have been made
[21:31] <jared_j> onItemsReady Doesn't really corrispong to onBegi
[21:31] <ccmitchell> onResult
[21:31] <ccmitchell> onResultComplete
[21:31] <jared_j> If we have onResultComplete, do we really need an onComplete?
[21:32] <brian_skinner> i think we need a separate onComplete that does *not* provide an array of items
[21:32] <brian_skinner> so that you can do...
[21:32] <slightlyoff> wait, can't you just ignore the args?
[21:32] <brian_skinner> result.fetch({onBegin:foo, onItem:bar, onComplete:iggy})
[21:33] <slightlyoff> jsut connect() to it w/ a 0-arity function?
[21:33] <ccmitchell> y, the func would be responsible to look for items or not
[21:33] <brian_skinner>
slightlyoff: if the fetch is going to return 100,000 items, then it we
need to be able to *not* put them in an array
[21:33] <slightlyoff> ah, OK
[21:34] <brian_skinner> we want to make the array available by request, but not by default
[21:34] <ccmitchell> so, one option is onComplete, with optional items array as arg
[21:35] <ccmitchell> depending on 1000000 item usage versus simple usage
[21:35] <jared_j> As determined by some setting on the find?
[21:35] <jared_j> saveResult or whatnot?
[21:35] <jared_j> Whether or not to generate and pass an array?
[21:35] <ccmitchell> if you dont find items in your complete, you know to fetch them
[21:36] <jared_j> Or by the mere presense of an onItem function, don' generate the array.
[21:36] <brian_skinner> jared_j: i think that's a good option
[21:36] <slightlyoff> so is getting 100K items going to be tennable along any other axis?
[21:36] <brian_skinner> +1
[21:36] <brian_skinner> slightlyoff: yes
[21:36] <brian_skinner> for streaming results
[21:36] <slightlyoff> brian_skinner: hrm, OK
[21:36] <slightlyoff> brian_skinner: but in that case we'd never generate an array that says "this is it" anyway, right?
[21:36] <jared_j> ?Okay, so if onItem is defined, onComplete isn't passed any items.
[21:37] <brian_skinner> MSFT stock ticker
[21:38] <brian_skinner>
slightlyoff: yes, in the streaming case, the onComplete might *never*
get called, or might only get called after a few hours
[21:38] <brian_skinner> and no array should ever be generated
[21:38] <brian_skinner> jared_j: +1 I like that option
[21:38] <jared_j> Yeah, for Datastores that have huge item lists, it may never reach the 'end of stream'.
[21:39] <brian_skinner> or for a datastore that's really a comet-based IRC chat, for example
[21:39] <slightlyoff> right, OK, so what's the non-streaming case that we care about? what's the current call syntax for that?
[21:40] <brian_skinner> like, to get all the records in a simple CSV file?
[21:40] <brian_skinner> result.fetch({onComplete:callback, saveResult:true})
[21:40] <brian_skinner> or
[21:40] <jared_j> store.find{query:<whatever>, count: 10, onComplete: foo); Return the first ten items found.
[21:40] <brian_skinner> result.fetch({onItem:callback})
[21:41] <jared_j> Why do we need saveResult?
[21:41] <jared_j> If there is an XOR relationship between onItem and onComplete?
[21:41] <brian_skinner> jared_j: wait, do we allow an onComplete in find() as well as fetch()?
[21:41] <jared_j> Yes.
[21:41] <jared_j> onComplete exists on both find and fetch
[21:41] <brian_skinner> why?
[21:42] <jared_j> Because that's the way it was agreed upon some ages ago (In which I wasn't involved). I don't have the history.
[21:42] <jared_j> How else do you know when your find has finished?
[21:42] <brian_skinner> i don't think you need to know
[21:42] <jared_j> And you can actually do a fetch?
[21:42] <brian_skinner> you get a result back instantly, and then you do a fetch() on it
[21:43] <brian_skinner> regardless of whether the find() is still finding
[21:43] <jared_j> Hm.
[21:43] <brian_skinner> so your fetch may just take a little longer to get goign
[21:43] <jared_j> I don't know if I like that
[21:43] <ccmitchell> n, the initial find is also asnyc
[21:43] <jared_j> Who's going to schedule that the fetch() waits for the initial find to finish?
[21:44] <jared_j> That's my concern. Maybe it's a bogus one.
[21:44] <brian_skinner>
have i mentioned lately that i think this whole idea of splitting apart
find() and fetch() just leads to more problems than it solves ;-)
[21:44] <brian_skinner> jared_j: the datastore
[21:44] <jared_j> *how* ? :)
[21:45] <jared_j> What apis do we have today make it easy for the Datastore author to do that?
[21:45] <slightlyoff> brian_skinner: well, it seems like we're trying to shoehorn 2 different things into the generic API
[21:45] <slightlyoff> streaming data stores are really quite different than the common-case request/response data stores
[21:45] <ccmitchell> we went the combined find/fetch route, and it was confusing to use
[21:46] <brian_skinner>
ccmitchell: i think we could try harder at making it less confusing,
rather than ditching it -- i can write up another proposal
[21:46] <slightlyoff>
generally, I think you want to be able to say "find stuff that matches
this, now get me the data from that" and you need to know when it's all
there
[21:47] <slightlyoff> I'll admit to a little frustration here
[21:47] <ccmitchell> y, find stuff ( and let me know that the find is occuring or not), then i fetch the results
[21:47] <slightlyoff> we're 15 minutes from the end of a 2hr meeting and we're talking about ditching the fundamental design?
[21:47] <brian_skinner> slightlyoff: why say that, when you could instead say "find stuff that matches this and give it to me"
[21:47] <slightlyoff> less than a month from M1
[21:47] <slightlyoff> and after a year of design
[21:48] <ccmitchell> i really like the new api...it's close lets not drastically change at this point
[21:48] <ccmitchell> feedback from other teams that are writing ds's in ibm are that it makes more sense to them
[21:48] <brian_skinner>
i wouldn't say we're ditching fundamental design -- we just have one
dissenting voice (me) suggesting that we reconsider a decision that was
only made two weeks ago
[21:48] <slightlyoff> brian_skinner: because we need to layer things
[21:49] <slightlyoff>
brian_skinner: we need to implement query semantics somewhere and we
need to implement caching strategies somewhere
[21:49] <brian_skinner> yup, understood -- i think we can do taht
[21:50] <slightlyoff>
brian_skinner: and, frankly, I don't care where so long as it's not the
users problem to be passing references around willy nilly to get it done
[21:50] <brian_skinner> yuip
[21:50] <slightlyoff> brian_skinner: which was my main objection to the old API
[21:50] <slightlyoff> brian_skinner: now, I'd move that we not conflate streaming data stores w/ common-case
[21:50] <brian_skinner>
whatever the API looks like, in the end the datastore will need to be
responsible for both queries and caching
[21:51] <slightlyoff> brian_skinner: and perhaps provide ordinals for them to fill in to common-case events
[21:51] <brian_skinner> slightlyoff: i don't understand the problem with conflating those?
[21:51] <slightlyoff> brian_skinner: or let them provide Deferreds instead of real results
[21:51] <slightlyoff>
brian_skinner: because it sounds like we're about to morgtage
common-case simplicity in order to satisfy them
[21:51] <brian_skinner> why add in Deferreds -- what problem does that solve
[21:52] <brian_skinner>
slightlyoff: i don't understand -- i don't see that the streaming case
is in any way making anything else more complicated
[21:52] <slightlyoff>
brian_skinner: I'm just saying that we need to provide a simple way for
users to know that they aren't getting all the data and that they can't
expect to, right?
[21:52] <brian_skinner> i'm not sure we need to do that at all
[21:53] <slightlyoff>
as I see it, you can either say "this type of data source will never
use these events", or you can say "this data source will respond w/
something special for these kinds of events"
[21:53] <slightlyoff>
but the other options leave you w/ strange semantics that say something
along the lines of "well, if you're using this kind of data store, this
is the whole thing, but in other cases it might not be"
[21:54] <brian_skinner> can't we just say that all datastores provide for find(), onBegin, onItem, etc?
[21:55] <brian_skinner>
maybe IRC isn't the best tool for this discussion -- i feel like we're
mixing together more than one question, and the low-bandwidth makes it
hard to tease them apart
[21:55] <ccmitchell> other option is to have both a SyncRead and AsyncRead api
[21:56] <slightlyoff> ccmitchell: but async solves an important request/response problem
[21:56] <ccmitchell> but i think just sticking with the asynch case is the only common solution
[21:56] <slightlyoff> (namely that of network latency)
[21:56] <slightlyoff> ccmitchell: I think we need to say:
[21:56] <slightlyoff> reads are async, the difference is if the API will let you read the whole thing or not
[21:57] <brian_skinner> jared_j: sorry, i never managed to respond to the question you raised a few minutes ago
[21:57] <slightlyoff>
brian_skinner: is there time this week that we can meet? or are you
suggesting a phone conference or something?
[21:57] <brian_skinner> too many questions all at once
[21:58] <ccmitchell>
that's the approach we've been going down...so... onComplete() or
onComplete(items), with onComplete() used if onItem() handler specified
[21:58] <brian_skinner>
slightlyoff: phone would be fine -- or e-mail or wiki -- or I can meet
up with you in San Francisco (that leaves out everybody who's not in
the bay area, but might still be useful)
[21:58] <ccmitchell> we can do a telecon as well, no prob
[21:58] <jared_j>
brian_skinner: How does meeting with slightlyoff alone help when I'm
the one currently implementing this stuff? I think I need to be present
too.
[21:59] <slightlyoff> jared_j: yes, of course
[21:59] <brian_skinner> jared_j: yup
[21:59] <slightlyoff> so as I see it, we have 2 big schisms in design decisions:
[21:59] <jared_j>
I'm having a hard enough time trying to wrap my brain around everything
going on without having shadow conversations going on. :/
[21:59] <slightlyoff> 1.) big data vs. small data
[22:00] <ccmitchell> local/remote
[22:00] <slightlyoff> 2.) request/response vs. streaming
[22:00] <brian_skinner>
i was just thinking that if at least slightlyoff and i understood each
other, that would lead to one less potential source of confusion in the
IRC meetings
[22:00] <brian_skinner> graph/list
[22:01] <brian_skinner> or list/tree/graph
[22:01] <ccmitchell> we'll need to address these latter cases for Tree binding
[22:02] <slightlyoff> but we've got reasonable solutions for everything *but* streaming/request-response
[22:02] <ccmitchell> to me, find() is fundamentally a different operation than fetch()
[22:02] <brian_skinner> slightlyoff: i think we also have a reasonable solution for streaming
[22:02] <ccmitchell> i expect to know the result of a find, independent of how i retrieve the results
[22:03] <brian_skinner> ccmitchell: that's fine -- a separate find() and fetch() is the plan of record
[22:03] <ccmitchell> can we put some syntactic sugar onto the case where you know the find results in all items available
[22:04] <slightlyoff>
brian_skinner: ok, well, then I'm unclear about how the semantic that
lets me say "hand me the results" also works for streaming w/o ambiguity
[22:04] <slightlyoff> brian_skinner: or at least one that's not much harder to introduce
[22:05] <brian_skinner>
how about we start a wiki page that just shows examples of what using
the APIs looks like, in each of the different cases -- streaming,
paging, etc.?
[22:05] <slightlyoff> brian_skinner: ok
[22:05] <brian_skinner> a half dozen simple examples
[22:05] <slightlyoff> brian_skinner: when will we have a decision on this?
[22:05] <slightlyoff> brian_skinner: can it be done by mailing-list vote?
[22:06] <brian_skinner> a decision on what?
[22:06] <ccmitchell> well need the wiki page to document these scenarios anyway, so +!
[22:06] <slightlyoff> brian_skinner: on locking down these dangling bits of the read API
[22:06] <ccmitchell> +1
[22:06] <slightlyoff> ccmitchell: I like +! ;-)
[22:07] <ccmitchell> we're overtime now... want to discuss again thurs?
[22:07] <slightlyoff> works for me
[22:07] <brian_skinner>
slightlyoff: i think the saveResult vs onComplete(items) is a very
small dangling bit -- we can push to lock it down this week, but i
don't think it should let it keep you up at night
[22:08] <brian_skinner> i'm free thursday
[22:08] <jared_j> Thursday is fine. Same time?
[22:08] <brian_skinner> or next tuesday
[22:08] <brian_skinner> either is fine
[22:08] <slightlyoff>
brian_skinner: not having it marked "done" is what's got me
worried...lots of the rest of the project needs this stuff done
[22:08] <ccmitchell> lets continue with saveResult/onComplete then on Thurs, plus remaining agenda items from today
[22:09] <slightlyoff> brian_skinner: as someone said at 3D2: "shipping is not a natural act"
[22:09] <jared_j> I'd like to get this locked down so I can pass the stuff to Brian to get checked in to get Doug off my back. :)
[22:09] <slightlyoff> jared_j: = )
[22:09] <brian_skinner> okay
[22:09] <jared_j> Not to mention get progress onmoving what we can in into core for M1, of course.
[22:09] <jared_j> Time's a ticking.
[22:09] <slightlyoff> yep
[22:09] <ccmitchell> before we go, i made an assertion earlier that i want to make sure brian/alex agree with
[22:10] <brian_skinner> ccmitchell: yup, shoot
[22:10] <ccmitchell> only apis, JSONItemStore and XMLItemStore in dojo.data
[22:10] <jared_j> As core stores?
[22:10] <brian_skinner> vs dojox.data?
[22:10] <ccmitchell> all others in dojox.data or specific dojox projects, like dojox.atom
[22:10] <jared_j> Move Yahoo, delicious, etc, to dojox?
[22:10] <ccmitchell> jared: y
[22:10] <brian_skinner> i'm fine with that
[22:10] <slightlyoff>
ccmitchell: that sounds fine for Core, but if there's overwhelming
support for other stores, we can consider them for Core
[22:11] <slightlyoff> great
[22:11] <ccmitchell> y, start small
[22:11] <jared_j> agreed.
[22:11] <slightlyoff>
there will be a chance to move things to core once they've settled
down, but the burden on Core code is much higher
[22:11] <jared_j> Brian, are you going to put up the wiki page mentioned?
[22:11] <slightlyoff> so for your own sanity, I would suggest moving the bulk to dojox
[22:12] <ccmitchell> alex, fyi, jared's got an atom feed and io transport that we'd like to contribute to dojox.atom in M2
[22:12] <jared_j> I thought we were keeping that in-house, Chris?
[22:12] <jared_j> That was plan of record last I knew.
[22:12] <brian_skinner> jared_j: i can work on that tomorrow -- or, if you want to start it, i can add to what you start
[22:12] <ccmitchell> that would be plan B :) if they community says they dont want
[22:13] <jared_j>
I mean, M2 is end of april, I thought. I don't see it as concievable to
get everything we already have listed for M2, + that, by end of Apirl.
[22:13] <ccmitchell> not concievable for u
[22:13] <ccmitchell> alone
[22:13] <jared_j> Not unless you want me to go insane, anyway.
[22:13] <ccmitchell> jared: stop by, i'll explain offline
[22:15] <slightlyoff> ccmitchell: well, when you guys decide, let me know = )
[22:15] <slightlyoff> ccmitchell: sounds like a really neat feature
[22:15] <jared_j> Would you want it if we have it? That's the main question.
[22:15] <jared_j> So, sounds like you would.
[22:16] <slightlyoff> jared_j: if you'll maintain it, we'd love to have it
[22:16] <jared_j> Ok. We'll see what we can do.
[22:17] <slightlyoff> see everyone thurs
[22:18] <brian_skinner> thanks
[22:18] <jared_j> Bye.
[22:18] * slightlyoff (n=alex@204.14.154.182) Quit ()
[22:19] * jared_j (i=chatzill@nat/ibm/x-734ae8b1a691015a) Quit ("Chatzilla 0.9.77 [Firefox 1.5.0.10/2007021601]")
[22:22] * ttrenka (n=ttrenka@c-24-131-182-228.hsd1.ma.comcast.net) Quit ()
[22:23] * hamster74 (n=Miranda@82.84.69.249) has joined #dojo-meeting
[23:02] * hamster74 (n=Miranda@82.84.69.249) Quit ()
[23:06] * jared_j (n=chatzill@cpe-071-077-064-047.nc.res.rr.com) has joined #dojo-meeting
[23:06] <jared_j> Isn't there a dojo dijit meeting here tonight?
[23:13] * |ccmitch| (n=kvirc@cpe-024-211-158-152.nc.res.rr.com) has joined #dojo-meeting
[23:14] <|ccmitch|> no dijit irc tonight?
[23:14] <jared_j> Doens't look like it.
[23:15] <|ccmitch|> k, talk to you in the morning
[23:15] * |ccmitch| (n=kvirc@cpe-024-211-158-152.nc.res.rr.com) Quit (Client Quit)
[23:16] * jared_j (n=chatzill@cpe-071-077-064-047.nc.res.rr.com) Quit ("Chatzilla 0.9.77 [Firefox 1.5.0.10/2007021601]")
These logs were automatically created by DojoMeetingBot on
irc.freenode.net
using the Java IRC LogBot.
Hide quick tip X
Quick Tip: Link to Other Wiki Pages
Use the Link function to link to an existing wiki page, a new wiki page, a document, or a URL.
| |
File |
By |
Size |
Attached |
Ver. |
|