On iterative, open source documentation (or lack thereof)

AOL has put together developer.aol.com to highlight its contributions to the web community, but one of AOL’s earliest contributions, AOLserver, is silent from the list. (Yes, I did mention this to someone internally at the end of May 2006, and projects that have launched since have made it to the list, already.)

Jeremy Zawodny expresses what I’ve been trying to put into words for a while now about the difficulty of contributing previously closed source, which AOLserver was prior to 1999. The AOLserver community has always been anxious to see more of AOL’s closed source components for AOLserver get released as open source, most famously the “DCI” collection of modules which was invented as part of the AOL Digital City (now AOL CityGuide). So, what’s kept AOL from “being a better open source citizen” (if that’s really what it would mean) and releasing the DCI modules?

Jump-starting an open source community like AOLserver with a sizable and previously closed source codebase presents an interesting challenge. Most likely, the design discussions were held in face-to-face meetings, some now outdated design documents may have been created and the software was constructed under commercial pressures with all the sacrifices and trade-offs that come with them. Much of the knowledge and design rationale is primarily locked up in two artefacts: the initial developers’ brains and the produced code itself. Releasing any portion of the code alone significantly raises the bar of required understanding for participation and contribution. Making those brains available in the form of community participation (i.e., answering questions) means dedicating some non-zero percent of your most valuable asset: your people.

Contrast this with an open source community that starts from scratch, with nothing at the start. All design discussions are generally held using communication methods that are easily archivable and searchable. Even if no explicit design document artefacts are produced before software construction, a determined software design archeologist could pore over the chat logs and transcripts and mailing list archives to reconstruct the key points that drove the design using resources that are already publically available. After the documentation is started this way, the community can continue to refine and contribute to it through distributed collaboration tools, which is why I’m a big fan of Wiki software.

Is this documentation really that necessary? Again, for some people, probably not: the bar of required understanding is low enough for them. But, that set of people is quite small. There are folks at AOL who have full access to all our source code who still can’t make heads or tails of our stuff, who need serious hand-holding to make things just work. Imagine the difficulty a member of the community would have, not having access to all the code and all the people who know it well. For many, making more of our closed source code open would be next to useless to them. So, where’s the rush to open it up until all the necessary prerequisites (documentation, examples, etc.) are available?

So, given the situation, does this make AOL (or Yahoo!, or Google) poor open source citizens because it hasn’t put a license on more of its code and made it available to the community? Does it necessarily imply that the quality of the code is poor because it’s not easily open sourced? Is there a lesson about gift horse mouth inspection going on, here? I can’t speak for Yahoo! or Google, but take my word for it that the members of the AOLserver community who work at AOL have been continuing to clean up and better document more of the still-closed source AOLserver modules (like the DCI modules) with intent to eventually release them.

Tags:
,
,
,
,
,

I saw the Witch Doctor and she told me what to do …

So, back in April I separated from my family because I just couldn’t live with them any more. After a month and several phone calls back and forth, my wife and I agreed to give things another chance and I came back home. Divorce didn’t really seem like a workable solution. The time apart helped me see that I really cared way too much about things that really didn’t matter. As apathetic as I thought I was before, I’m far more apathetic now and my life’s actually improved as a result.

After returning, I decided to find a new therapist. The one I’d been seeing for the last few years just wasn’t getting me anywhere. So, after a bit of procrastination, I’d made appointments to see a new psychiatrist and new psychologist. I wasn’t looking forward to starting all over again, but then, what did I have to lose? Towards the end of July, I met my new psychiatrist, Dr. P., and my new psychologist, Dr. H.

I’ve never tried antidepressants. Not because I thought I didn’t need them, but because I think selection is too random since we lack of sufficient understanding of the brain. Of course, the psychiatrist suggested I try out Paxil CR and started me on a 15mg dose for four weeks. Since my last visit, she’s recommended upping the dosage to 25mg and we’ll see how that goes. I’ll be finishing up the 15mg pills later this week and will start the 25mg right after.

If I was apprehensive about starting new drugs, I’m even more so about starting with a new psychotherapist. I’m not sure I believe that problems can be fixed by talking. In our first session, I speed-rambled through about 7 years of highlights between 1999 and 2006 as best I could in 45 minutes. I’m sure I missed a lot of important details, but I wanted to give Dr. H. an idea of where I’d been emotionally the last several years. During the conversation, I’d mentioned that I have what I’ll summarize as identity and acceptance issues: I’m perfectly comfortable with myself–who I am–and accept myself. This works fine for me in isolation, but unfortunately there’s a whole world of people out there that I have to interact with, most importantly my wife and children. My wife has her own list of my personality flaws which she’d like to see changed, but I’m extremely apprehensive about making them arbitrarily: I’d much rather be the way I am than change the “wrong” thing about myself and end up hating myself. So, Dr. H. suggested that I start keeping a journal (perhaps, like this blog?) as a means for introspection. This way, I can start looking at my life more objectively and come up with my own list of things I dislike about myself and then we can work on making changes through therapy. I definitely like this suggestion, but I need to overcome my inability to put my thoughts into writing which is a huge problem for me.

Consider this blog entry the first step in my self-improvement.

Tags: , , , , , , ,

Dr. Demento 20th Anniversary Collection (2-CD set)
If you were looking for the David Seville “Witch Doctor” song, I suggest you check out the Dr. Demento 20th Anniversary Collection. It is a 2-CD set and the “Witch Doctor” song is on the first CD, track15.

del.icio.us/dossy links since July 31, 2006 at 09:00 AM

del.icio.us/dossy (RSS) links since July 31, 2006 at 09:00 AM:

del.icio.us/dossy links since July 24, 2006 at 09:00 AM

del.icio.us/dossy (RSS) links since July 24, 2006 at 09:00 AM:

I know a guy, who knows a girl, who knows Mel Gibson!

Apparently, Mel Gibson was busted for a DUI arrest. If driving under the influence wasn’t bad enough, he was apparently throwing out anti-Semitic remarks in the process. He’s since apologized for his behavior, but that’s not what really worries me. What worries me is this:

Mel Gibson (credit: http://bear-blog.blogspirit.com/images/medium_mel-gibson.4.jpg)
Osama Bin Laden (credit: http://www.nndb.com/people/669/000023600/osama-med.jpg)

Is Mel too deeply involved in some method acting for a new role where he plays an anti-Semitic Muslim terrorist, or was he just losing his mind?

Also, to give credit where it’s due, the title of this blog entry is a take-off of an Adam Sandler song (which, sadly, I can’t find a reference to–Google, you have failed me!) … who, by the way, is a Jew. Okay, that was a complete non sequitur.

(via [info]substitute)

Tags:
,
,

Dilbert: Where’s your artificial sense of urgency?

Dilbert, 2006-07-25

Dilbert, to PHB: Is it more important to follow our documented process or to meet the deadline?
Dilbert: I only ask because our deadline is arbitrary and our documented process was pulled out of someone’s lower torso.
PHB: Where’s your artificial sense of urgency?
Dilbert: Teamwork killed it.

Some days, I swear, Scott Adams must be following me around, watching me work.

Tags:
,
,
,

Our nine senses? Exactly what is a sense, anyway?

Mark Poesch asks on his blog, “Why is it that all children are taught that they have only “five senses”…. Doesn’t a sense of gravity (i.e., acceleration) count as a sixth? …could you live without it?” I responded in the comments that I tend to think that it falls under the sense of “touch” as there’s a physical mechanism in the inner ear–specifically, the macula utriculi and macula sacculi[1]–that is responsible for our sense of gravity or linear acceleration.

No surprise, the Wikipedia entry for “sense” points out that the definition of “sense” isn’t well defined. Given a certain definition of sense, there are nine human senses: vision (sight), audition (hearing), gustation (taste), olfaction (smell), tactition (touch), thermoception (heat, cold), nociception (pain), equilibrioception (balance, gravity), proprioception (body awareness). So, it seems Mark is right, conventional wisdom considers gravity its own separate, dedicated sense.

However, in the comments to his blog entry, I asked: “What about “sense of time”? Is that simply cognition (and not a sense)? Probably.” Of course, Wikipedia has an entry on “sense of time” too, which says: “Although the sense of time is not associated with a specific sensory system, the work of psychologists and neuroscientists indicates that our brains do have a system governing the perception of time.” Why isn’t it associated to a specific sensory system? Is the prerequisite for a sense that it must have a corresponding sense organ? This can’t be, since thermoception, nociception and proprioception fail to meet this criteria. If senses are the perception of stimuli, the passing of time definitely causes a stimulus which we perceive.

It appears that back in 2001, researchers identified that the basal ganglia and the parietal lobe are responsible for perceiving the passage of time. Perhaps this provides for a solid explanation for deja vu and other temporal sensation anomalies?

What do you think? Share your thoughts in the comments below.

Tags:
,
,
,
,

del.icio.us/dossy links since July 17, 2006 at 09:00 AM

del.icio.us/dossy (RSS) links since July 17, 2006 at 09:00 AM:

So, what’s wrong with the new AOL CityGuide Beta?

AOL CityGuide Beta logo

The beta of AOL CityGuide was announced today (see the list of cities in beta). Since my current project–you know, the one that makes me want to find a new job–is tangentially involved with CityGuide, I have some interest in the product.

As Jason Calacanis says, “the first step in sucking less is knowing that you suck.” Unfortunately, society has been so severely perverted by political correctness that folks can’t tolerate anything but constructive criticism. Frankly, that’s a big wad of bull-hooey. Sometimes, your best feedback comes from those who are the most passionate and that can sometimes lead to angry flailing. You can trust me that I’m smart enough to read what you write, listen to what you mean and appreciate the time you took to share it. It’s more important to me that you tell me the truth than the way in which you express it. So, in that spirit, I put forth a few questions:

  • What do you hate about the new AOL CityGuide beta?
  • What features are missing? Looking for something you can’t find?
  • What is wrong with it? Anything broken or stupid?
  • What would it take to make you want to use the product?

Of course, I’d love to hear your positive feedback, too! Tell me what you love about the product, what you find most useful, how you couldn’t live without it, and so on. I’m sure the folks working hard on the product would appreciate hearing it, now and then. But, I think if we listen to and act on the negative feedback, it will lead to more people eventually giving positive feedback, so tell me what’s on your mind.

Oh, and just in case you’d never seen the AOL CityGuide product, here’s a quick visual comparison, with links to both:

Before:

After:

Tags:
,
,

Multiple threads opening the same Berkeley DB in Tcl

Thanks to the Tcl thread extension, you can use threads within your Tcl scripts with a thread-enabled build and this extension. There’s also a Tcl binding for Berkeley DB (BDB) available, as well. But, what if you want to combine the two, and access the same Berkeley DB from multiple threads in Tcl? Since Berkeley DB is free-threaded (or thread-safe), this should be simple, right? You’re right, it should be but it was pretty non-obvious, to me at least.

It’s not a bug, it’s just an undocumented feature!

First off, the BDB documentation makes mention of DB_THREAD needing to be set on the environment handle to get the free-threaded behavior, but the berkdb env documentation lacks any mention of how to do this. Turns out, the parameter -thread is undocumented, but does set DB_THREAD as expected. Fantastic! That’s all you should need to know, right? Wrong. There’s a peculiar constraint (bug?) which I ran up against, scratching my head, reading (and re-reading) the BDB source, trying to understand. Here’s an example script I started with:

package require Thread

set t1 [thread::create]
thread::send $t1 {
  package require Db_tcl
  set e [berkdb env -create -home bdb -thread -cdb]
  set db [berkdb open -env $e -thread -create -hash tables.db test]
}
thread::send $t1 {$db put foo bar}
  # => 0
thread::send $t1 {$db get foo}
  # => {foo bar}

set t2 [thread::create]
thread::send $t2 {
  package require Db_tcl
  set e [berkdb env -create -home bdb -thread -cdb]
  set db [berkdb open -env $e -thread -create -hash tables.db test]
}
thread::send $t1 {$db get foo}
  # => error: NULL db info pointer

You’d think this would work, right?

Naturally, what’s happened here is that two threads have attempted to use the same environment, and when the second thread does it, it invalidates the environment for the first thread, resulting in the “NULL db info pointer” error. Fine, I wouldn’t expect this to work for just this reason, so lets try to create the environment once and reuse it in the child threads. We’ll use tsv‘s (thread-shared variables) to share the environment handle across threads.

package require Db_tcl
package require Thread

tsv::set bdb env [berkdb env -create -home bdb -thread -cdb]
  # => env0

set t1 [thread::create]
thread::send $t1 {
  package require Db_tcl
  set e [tsv::get bdb env]
    # => env0
  set db [berkdb open -env $e -thread -create -hash tables.db test]
    # => error: db open: illegal environment
}

Illegal? I’ll show YOU illegal!

This really puzzled me, getting the “db open: illegal environment” error. I looked at the source for db-4.2.52, in file tcl_db_pkg.c around lines 1464–1473:

   1464         switch ((enum bdbenvopen)optindex) {
   1465         case TCL_DB_ENV0:
   1466             arg = Tcl_GetStringFromObj(objv[i], NULL);
   1467             envp = NAME_TO_ENV(arg);
   1468             if (envp == NULL) {
   1469                 Tcl_SetResult(interp,
   1470                     "db open: illegal environment", TCL_STATIC);
   1471                 return (TCL_ERROR);
   1472             }
   1473         }

I mean, look at that. NAME_TO_ENV() is a macro that’s defined as (DB_ENV *)_NameToPtr((name)) which simply fishes data out of DBTCL_GLOBAL __dbtcl_global … it shouldn’t be returning a NULL, here. What gives? Since we have to initialize each thread’s state on creation (it doesn’t inherit anything from the thread that created it), we have to package require Db_tcl and load the BDB module in each thread. I bet there’s something goofy going on there. Looking at Db_tcl_Init(), we see:

     72 int
     73 Db_tcl_Init(interp)
     74     Tcl_Interp *interp;     /* Interpreter in which the package is
     75                      * to be made available. */
...
     97     LIST_INIT(&__db_infohead);
     98     return (TCL_OK);
     99 }

Aha! The villain is revealed!

Oh, look, it initializes the global each time the package is loaded! So, the list that points to the environments gets wiped out once our newly created thread loads the Db_tcl package. While this is frustrating, there’s a work-around: create the environment after creating the threads and loading the Db_tcl package inside of them:

package require Db_tcl
package require Thread

## Create our threads, making sure Db_tcl is loaded.
set t1 [thread::create]
thread::send $t1 {
  package require Db_tcl
}
set t2 [thread::create]
thread::send $t2 {
  package require Db_tcl
}

## Now, we can create the environment once:
tsv::set bdb env [berkdb env -create -home bdb -thread -cdb]

## ... and then, use it in our threads:
thread::send $t1 {
  set e [tsv::get bdb env]
  set db [berkdb open -env $e -thread -create -hash tables.db test]
}
thread::send $t2 {
  set e [tsv::get bdb env]
  set db [berkdb open -env $e -thread -create -hash tables.db test]
}

## See:
thread::send $t1 {$db put foo bar}
  # => 0
thread::send $t1 {$db get foo}
  # => {foo bar}
thread::send $t2 {$db get foo}
  # => {foo bar}

All this, for what?

So, this is how the story ends. It is possible to use BDB across multiple threads in a Tcl application, with the restriction that all threads that will load the Db_tcl package must be created and initialized before you create environments and probably any other operation that relies on the __dbtcl_global structure, as it gets initialized on package load and the single global is shared across all threads. Presumably, this might be considered a bug, in that the structure should probably only be initialized once per process rather than every package load.

Can I do something about it now?

Here’s my proposed patch to fix this, although there’s a potential race
condition here:

$ diff -u tcl_db_pkg.c.orig tcl_db_pkg.c
--- tcl_db_pkg.c.orig   2006-07-17 11:22:20.000000000 -0700
+++ tcl_db_pkg.c        2006-07-17 11:23:40.000000000 -0700
@@ -78,6 +78,7 @@
 {
   int code;
   char pkg[12];
+    static int initialized = 0;

   snprintf(pkg, sizeof(pkg), "%d.%d", DB_VERSION_MAJOR, DB_VERSION_MINOR);
   code = Tcl_PkgProvide(interp, "Db_tcl", pkg);
@@ -98,7 +99,10 @@
   (void)Tcl_LinkVar(
       interp, "__debug_test", (char *)&__debug_test,
       TCL_LINK_INT);
-  LIST_INIT(&__db_infohead);
+    if (!initialized) {
+        initialized = 1;
+        LIST_INIT(&__db_infohead);
+    }
   return (TCL_OK);
 }

My recommendation would be to load the Db_tcl package in a single-threaded environment (before any additional threads are created) to ensure that only one thread initializes __db_infohead, then you can freely create threads and load the Db_tcl package in them without each package load re-initializing the __db_infohead.

If this was helpful, feel free to let me know in the comments below. Or, if you have any questions, ask those too!

UPDATE: I received a response from an Oracle engineer (who now owns Sleepycat) about this issue. Here’s it is:

[…] Although the fix you sent in the SR is one of the
ones needed to allow threaded access to BDB’s Tcl API, it is
not the only one. The __db_infohead is the beginning of a
global linked list and manipulation of that linked list is
not protected in the API. All manipulation of it would need
a mutex. That isn’t necessarily hard, but we have not had
customer demand for multi-threading the Tcl API.

I have fixed our Reference Guide Programming Notes on Tcl to
include a statement that says it does not support multi-threading.

So, if you’d like to see full threaded support in Tcl for Berkeley DB, leave a comment below and we’ll see what kind of demand really exists for it. In the meantime, I might try to work on it myself, just in case.

Tags:
,
,
,