Hopbot log for 2007-11-01 - Helma IRC channel: #helma on irc.freenode.net

2007-11-01:

[0:31] <drbobb> dang, it sure isn't easy to figure out java.nio based on sun's javadocs
[0:43] <BSlivka> Helma scheduling: I can only find reference to some old plan to change what it is. I Cannot find what helma currently uses in 1.6
[0:52] <BSlivka> Found it.
[0:52] <BSlivka> nevermind
[1:24] <midnightmonster> scheduling? like cron jobs?
[2:07] <BSlivka> yeah
[2:08] <BSlivka> there's cronjob methods on the app object
[2:08] <BSlivka> it turns out
[2:08] <midnightmonster> yup.
[2:08] <BSlivka> while I was searching though, I found a review you gave of Helma
[2:09] <BSlivka> and the project website you made with it.
[2:09] <BSlivka> for that preacher man
[2:09] <midnightmonster> right.
[2:09] <midnightmonster> I didn't finish updating the how-the-project-went site
[2:09] <midnightmonster> (did you see that? or just the finished site)
[2:09] <BSlivka> just the finished site
[2:10] <midnightmonster> but afaict crons get forgotten on app restart, so be sure to put the commands to create the job all in a function that you call onstart.
[2:10] <BSlivka> Aha!
[2:10] <BSlivka> there's an onstart event somewhere eh?
[2:11] <midnightmonster> just put function onStart(){ whatever; } in Global
[2:11] <BSlivka> Sweetness
[2:11] <BSlivka> I'm gonna write that down, it's genius
[2:12] <midnightmonster> mine looks like this: http://helma.pastebin.com/m3315cf8d
[2:12] <BSlivka> Yeah.
[2:13] <BSlivka> Myself, I'm doing something simple. I'm trying to make a searchable telephone list
[2:13] <BSlivka> and the best way to do that, I've found, from the information in an LDAP directory
[2:13] <BSlivka> LDAP is slow and stupid, so it's best not to tax it too much with request after request
[2:13] <BSlivka> better to periodically copy the information into a relational database
[2:14] <BSlivka> so I needed a cron job to synchronise the helma database with LDAP
[2:14] <midnightmonster> that's... odd. LDAP should be quite fast for the right kinds of queries
[2:14] <midnightmonster> But I've never implemented one, so I only know what I read.
[2:15] <BSlivka> Well, it's fast enough to just authenticate an individual user
[2:15] <BSlivka> against an ldap db
[2:15] <BSlivka> but if you want to pull up a list of names, and actually search through them,
[2:16] <BSlivka> it is taking me about 8-9 seconds to pull 180 names
[2:16] <BSlivka> with their requisite contact info etc..
[2:16] <midnightmonster> ick
[2:18] <BSlivka> You're probably supposed to be able to search using LDAP itself, but I'm just unfamiliar enough with LDAP queries that I wouldn't trust a function I wrote to dynamically generate them
[2:18] <BSlivka> generate the queries that is
[2:18] <BSlivka> so it seems like a better idea to me to spend about 30 seconds twice a day to just pull the names I need
[2:18] <BSlivka> and search them from that cache
[2:19] <BSlivka> which seems to be what most other programs do- There's two other preexisting applications on this network that do the same thing
[2:19] <BSlivka> One of them was microsoft- who also made the active directory server I'm using..
[2:20] <BSlivka> active directory is a sort of MS version of LDAP
[2:20] <BSlivka> so anyways, sorry to bore you, but that pretty much summarizes what I'm up to.
[2:21] <midnightmonster> no prob. I'm not bored, just in a cruch
[2:21] <midnightmonster> crunch
[2:21] <BSlivka> I'm off to have some luch
[2:21] <BSlivka> lunch
[2:22] <midnightmonster> where in the world are you? it's 10 PM here
[2:22] <BSlivka> australia
[2:22] <midnightmonster> spiffy. enjoy
[2:54] <midnightmonster> get(arg) <-- is arg is a string, get returns the child with that _name. but if arg is a numeric string, get() returns the child with that _id. what if my names all look like numeric strings?
[2:55] <midnightmonster> "is arg is" = "if arg is"
[2:56] <BSlivka> Then you use a string with numbers, I suppose
[2:56] <BSlivka> "1" "2" "3"
[2:57] <midnightmonster> nope, that'll retrieve the object with _id="2", not the object with _name="2"
[2:57] <BSlivka> ah..
[2:57] <BSlivka> hrmn that's a good point, I just reread that
[2:57] <midnightmonster> I actually have a workaround
[2:57] <BSlivka> that seems a bit dodgy
[2:57] <midnightmonster> for my case, but not general
[2:59] <midnightmonster> the public app needs pretty urls, and in an earlier conversation with someone I learned that you can use a string column for _id so long as you don't create any new whatevers. and the public app would never need to create new whatevers, only the admin side. so I can fake it for my needs.
[2:59] <midnightmonster> tg
[2:59] <midnightmonster> gtg
[4:15] <jkridner> global
[4:16] <jkridner> 'global' doesn't seem to be saved between requests, whereas 'app.data' is. I guess this is by design, but the documentation didn't make this clear to me.
[11:27] <zumbrunn> jkridner, regarding global not being preserved between requests...
[11:27] <zumbrunn> that's a new behavior in Helma 1.6.0
[11:31] <zumbrunn> (in other words, it's a very recent design change)
[12:08] <jkridner> oh. thanks.
[12:08] <jkridner> was it a good change?
[12:09] <jkridner> seems like it could be a significant issue for compatibility.
[12:11] <jkridner> zumbrunn, thanks. I was going to just now try to make a wiki comment, but it seems the documentation just underwent a significant upate.
[12:12] <jkridner> upate=update
[12:15] <jkridner> btw, I managed to get the openid4java library functioning under Helma. Getting my ConsumerManager object to be preserved between request was the last bit of magic. My next step is to try to map this to the existing User prototype.
[13:43] <zumbrunn> oh... in this context, using the global method defineLibraryScope('ConsumerManager') will make more sense than using the app.data cache
[13:43] <zumbrunn> that way global.ConsumerManager will survive between requests
[14:17] <zumbrunn> jkridner, you missed a reply
[14:17] <zumbrunn> http://helma.zumbrunn.net/hopbot/
[14:17] <zumbrunn> (13:43)
[14:18] <zumbrunn> http://helma.zumbrunn.net/reference/global.html#defineLibraryScope
[14:20] <jkridner> zumbrunn, I was just reading that. :)
[14:20] <jkridner> why would I add a new namespace?
[14:21] <zumbrunn> namespace is not really the right word for it
[14:21] <zumbrunn> neither is "garbage collection"
[14:21] <jkridner> it is least intuitive that this would preserve global.XXX by doing defineLibraryScope(XXX);
[14:21] <zumbrunn> it just protects the global property with that name from been cleared between requests
[14:22] <jkridner> is there not a single instance of 'global'?
[14:22] <zumbrunn> yeah, defineLibraryScope has wild history
[14:22] <zumbrunn> has a wild
[14:22] <zumbrunn> it was deprecated and undeprecated several times
[14:23] <jkridner> Is there a single instance of 'global'?
[14:23] <zumbrunn> per application yes
[14:24] <zumbrunn> plus a copy of it per request
[14:24] <jkridner> copy?
[14:25] <zumbrunn> not sure exactly
[14:25] <jkridner> is that a security issue?
[14:25] <zumbrunn> well, yes, can be
[14:25] <jkridner> are the apps isolated in some way for security purposes?
[14:25] <jkridner> do they run under the same interpreter instance?
[14:26] <jkridner> 'app.data' seems to clearly be preserved.
[14:26] <zumbrunn> not sure exactly, but the apps have completely separate scopes
[14:27] <jkridner> BTW, I don't know enough about web architecture to know how 'session.data' is preserved.
[14:28] <zumbrunn> global == this in the global scope ...just in case that wasn't clear
[14:28] <jkridner> I guess I'm not getting why there'd be any preference to using defineLibraryScope makes over app.data, especially since defineLibraryScope has been deprecated in the past.
[14:29] <zumbrunn> your example would be a possible use case.... the ConsumerManager
[14:31] <zumbrunn> without defineLibraryScope you would not be able to add any new objects to the global scope
[14:31] <zumbrunn> which wouldn't make sense in my opinion
[14:31] <jkridner> OK, but why would I want to? Doesn't it seem that app.data is the right place?
[14:31] <zumbrunn> you could modify existing ones, but not add new ones
[14:32] <zumbrunn> for some things, yes
[14:32] <jkridner> for ConsumerManager?
[14:32] <zumbrunn> if you want to cache "application data" for the lifetime of the app
[14:32] <jkridner> I need it at least for the life of the session.
[14:32] <zumbrunn> I think ConsumerManager is more an extension of the framework
[14:32] <jkridner> I wish I knew how session.data was preserved.
[14:32] <zumbrunn> not really "app data"
[14:33] <jkridner> not really, it is just part of the app for now.
[14:33] <jkridner> I'm expecting that the User should be extensible such that I can keep my custom User definition as part of my app.
[14:33] <zumbrunn> not sure what you are asking about session.data
[14:34] <jkridner> If I knew how session.data was preserved, I might be able to just use that for maintaining ConsumerManager.
[14:35] <jkridner> for clarity sake, ConsumerManager is the Java class org.openid4java.consumer.ConsumerManager.
[14:36] <jkridner> I need to have one instance of this manager that is preserved between my "Discovery" request and my "Verification" request.
[14:37] <jkridner> I'll RTFM on 'session'.
[14:38] <jkridner> Wikipedia seems to provide sufficient information.
[14:38] <zumbrunn> well, session.data.ConsumerManager would give you one instance per user
[14:39] <zumbrunn> while app.data.ConsumerManager gives you one instance per app
[14:39] <jkridner> right. I'm still trying to discover which is better. For security reasons, I'd think that one instance per user would be better.
[14:40] <jkridner> so, is Helma using server-side sessions? I'd guess that it is.
[14:40] <zumbrunn> yes
[14:40] <zumbrunn> tracked via a cookie
[14:40] <jkridner> k.
[14:41] <jkridner> that makes sense, since I'm currently maintaining a Discovery object and I would have been surprised if it was fully reconstructed via a client-side cookie.
[14:45] <zumbrunn> do you want to keep instances of org.openid4java.consumer.ConsumerManager?
[14:46] <zumbrunn> or just a reference to Packages.org.openid4java.consumer.ConsumerManager?
[14:46] <jkridner> I need to keep instances.
[14:47] <jkridner> I just tested using session.data, instead of app.data, and it works fine.
[14:47] <zumbrunn> note that session.data.foo becomes accessible in skins as session.foo
[14:47] <zumbrunn> <% session.foo %>
[14:49] <jkridner> that's a handy macro.
[14:51] <zumbrunn> just like req.data.foo --> <% request.foo %> and res.data.foo --> <% response.foo %>
[14:51] <jkridner> right. aren't those all solved using macros?
[14:51] <jkridner> that is, aren't there a bunch of default macros for the skins?
[14:52] <zumbrunn> well, these are kind of "built-in default macros"
[14:52] <zumbrunn> they aren't really "macros" in the helma sense
[14:52] <zumbrunn> macros are custom defined
[23:47] <drbobb> how weird
[23:48] <drbobb> by calling gc() in rhino a couple of times, i can make the free memory ( as reported by java.lang.Runtime.getRuntime().freeMemory() )
[23:49] <drbobb> *decrease* tremendously
[23:50] <BSlivka> So GC+ increases memory use?
[23:50] <BSlivka> err gc()
[23:53] <drbobb> free mem before gc(): 509604488
[23:53] <drbobb> /* 3 calls to gc() */
[23:54] <drbobb> free mem after gc(): 4310880
[23:54] <drbobb> the first figure is quite suspect
[23:55] <drbobb> i'm running the jvm with -Xmx512m
[23:55] <drbobb> it's unlikely that rhino's data structures take so little heap space
[23:58] <drbobb> ok so i launch the rhino shell, and as very first command do:
[23:58] <drbobb> print( 'free mem before gc(): ' + java.lang.Runtime.getRuntime().freeMemory() );
[23:58] <drbobb> free mem before gc(): 4556760

 

 

In the channel now:

Logs by date: