(picture)

July 29, 2003

Swarming

Computerworld, Meeting of the Minds:

Swarming is a type of collaboration in which large numbers of geographically dispersed people quickly self-organize in a peer-to-peer network to deal with a problem or opportunity. It's a fluid, shifting network with no central control or hub. A swarm can be as complex as a global business network or as simple as a "cell phone posse"

July 23, 2003

Jef Raskin interview

at Ubiquity: widely rambling, fascinating interview with Jef Raskin, the man behind the Mac (inter alia).

Another example is the absurd application of icons. An icon is a symbol equally incomprehensible in all human languages. Whatever language you know, you have to learn the meaning of an icon anew... Just look at a typical directory menu; a flood of identical icons distinguished only by (gasp) words! Ever notice that those little tips come up to explain icons are words? Note that we don't have little icons pop up to explain words.
And about THE,
I just call it "The Humane Environment" because it's meant to be humane. It treats human beings well. By contrast, the present GUI interface was meant to make conventional computer structures more accessible... The operating system is the program you have to hassle with before you get to hassle with the application. So instead of trying to gussy up everything and put these various wolves in sheep's clothing, I got rid of the wolves.

July 22, 2003

Groove, small business, and invisible infrastructure

BusinessWeek has a couple of stories worth reading: an interview with Ray:

At a very high level -- I know this is silly -- but the wildest vision is that [communication technology] disappears into the background and we don't think or talk about it anymore... You have to care about how people interact with one another and [about] social dynamics in order to be successful in this kind of endeavor. And so, if you find yourself talking about technology a lot, you're probably not thinking about the right thing.
and a story For Some, the Godsend of Groove:
Some of Groove's customers exhibit a frankly evangelical zeal for the product, and Lazar is no exception... "Our CEO at least once a day is cursing at me about our server and our networks, so I would love to see the day when all of that will disappear," he says. "I could really see just doing away with the network and doing all of our functioning on Groove. I think that is within the realm of possibility."
Of course "doing away with the network" doesn't mean you can actually dispense with connectivity, just that it disappears from your radar screen...!

July 21, 2003

hyki notes

It would be really interesting to use the hyki in a meeting. It's so very unstructured that repeated usage should quickly grow its own conventions - which I could imagine being packaged as "hyki templates", with for example a set of default pages for MeetingAgenda, MeetingAttendees, and so on.

The current version (all 5 hours' work...!) is rough, experimental, and unlikely to scale robustly. Basically it doesn't do "transaction distribution", it does "page distribution". In practice this means that (unlike Hydra and Groove text tool) page-level conflicts are resolved by "last edit wins", and that any simultaneous page edits are a conflict. Whereas, with a command-coordinating system, individual keystrokes or character-level edits could be applied independently on a page. With the "page distribution" model I'd need to get into performing HTML diff, and I really really don't want to go there.

But, again, I'm quite fascinated by the potential of a tool like this. Immediate enough to be useful face to face. Divergent enough to support an explorative, brainstorming group activity. Persistent and awareness-enabled enough to handle distributed groups too. If you want to take it for a spin together, drop me a note.

hyki

Ray blogs an awesome idea: "hyki". Hydra plus Wiki = hyki.

Of course I couldn't resist hacking one together, using Groove Web Services...

(update: added link to DW on NPR - a nice intro to the power of wikis)

July 17, 2003

Untrustworthy

BoingBoing: Firewalls are broken:

Firewalls are predicated on the notion that trustworthy people are inside your network and untrustworthy people are outside your network. Despite the obvious untruth of this -- the CEO goes home with her laptop and is treated as untrustworthy; an employee opens a trojan and has his box r00ted by a script-kiddie in Belarus, and is still treated as trustworthy -- we persist in using them, and then get surprised when they fail.
...pointing to a (fairly content-free) VNUnet article about the dangers.
Related: Ray; Jon Udell and PJ Connolly.

Out Of Office

Intranet Journal, Groove and Microsoft Take Office Out of the Office:

Groove Networks is getting its groove on with Microsoft's SharePoint in a pairing that brings big benefits to mobile intranet users. Separately, each product has a lot to offer, but together they offer an ideal solution for mobile professionals that neither alone can provide.
...The next level of the Groove/SharePoint collaboration...will offer two useful new features: document librarian and an integration with InfoPath, a new Office tool.

SVG Textorizer

Via Danny Ayers: the amazing SVG Textorizer Tool.

Zappa

Julian Bond quotes Frank: "Total Criminalization was the greatest idea of it's time and was vastly popular except with those people who didn't want to be crooks or outlaws. So they had to be tricked into it. Which is one of the reasons why Music was eventually made Illegal".

Stack overflow

Charles Miller: "I have a stack for significant tasks that is two deep. Any more and I crash".

July 16, 2003

JavaScript, asynchrony and closures

A couple of my GWS applications are driven by a fairly large chunk of JavaScript. There's some DHTML, then a slew of objects modeling Groove services, and they all call down to a SOAP helper, which uses XMLHTTP to talk to the Groove process. It's neat, and looks great, and I think it'll be maintenance-light.

Rather, I thought it would be maintenance-light. But one itch just had to be scratched: responsiveness. If Groove is very busy, or is prompting for password at the time, the HTTP call blocks. Which in this case means that my non-Groove application stops responding, too. And the startup performance isn't great, because I kick in when the application loads, and my GWS calls pretty much block the user interface until they're done.

To which there's only one solution: make the HTTP calls asynchronous. Here's where I'm really glad the stack is built in JavaScript: the result is nearly zero refactoring, because I can use closures. Gory details follow.

The bottom of the stack looks like this (Some, but not much, pseudocode mixed in here to keep it readable):


function SOAPCall(sReq,sURL,pObject)
{
var HTTP = CreateObject("Msxml2.XMLHTTP.5.0");
HTTP.open( sReq, sURL, false /* synchronous */ );
HTTP.setRequestHeader( "SOAPAction", theAction );
// ... build the message, then HTTP.send()
return parsed( HTTP.responseXML );
}

So, I build a SOAP message and punt it down the wire; the return message is some XML, which gets passed to a parser and a factory where the result (an object or an enumeration) is built and returned to the caller. Errors throw.

The caller has a nice high-level approach, for example:


var mydiv = // something local
var f = new g.GrooveFileDescriptor();
f.SetName( sFileName );
try
{
// this does a SOAP call
pStream = pFilesToolData.ReadFile( f );
// then use the stream (here, the contents of a text file)
mydiv.innerText = pStream.ReadText();
pStream.Close();
}
catch( _ex )
{
alert( _ex.description );
}

And there's a middle layer, where the GrooveFileDescriptor, GrooveFilesToolData and my other classes live.

Let's assume that we can make the HTTP calls asynchronously. My code will fire off a Web request, carry on running, and later be interrupted. But that SOAPCall() function can't have a meaningful return value anymore, because the request won't be done. Everything gets split into fragments. At the lowest level we have something like:


function StartSOAPCall(sReq,sURL,pObject)
{
var HTTP = CreateObject("Msxml2.XMLHTTP.5.0");
HTTP.open( sReq, sURL, true /* asynchronous */ );
HTTP.setRequestHeader( "SOAPAction", theAction );
// ... build the message, then HTTP.send()
}
function FinishSOAPCall()
{
// But how did we get here?
return parsed( HTTP.responseXML );
// And where does that 'return to'? The original caller is long gone...
}

and at the top, the code seems likely to become

var f = new g.GrooveFileDescriptor();
f.SetName( sFileName );
// kick off a SOAP call
pFilesToolData.ReadFile( f, CallbackFunction );
return;
...
function CallbackFunction( pStream /* and what else?? mydiv?? */ )
{
// use the stream (here, the contents of a text file)
mydiv.innerText = pStream.ReadText();
pStream.Close();
}
What other parameters might my callback need? Plenty, as it turns out (local variables, not just "this"). And what about error handling - where will errors be thrown to?

There's a simple switch on the HTTP object which makes it asynchronous: HTTP.open( sReq, sURL, true /* asynchronous */ );. Then you fire and forget; some while later, a COM event fires ("onreadystatechange"), and if readystate is "4", we have data. The "onreadystatechange" handler is can be set easily enough, but it doesn't get any context. Not even a pointer to the HTTP object which fired the event! How are we supposed to know what fired, to even find its readystate, let alone what we should do with it?

A singleton caller? - too clunky. Global variables? - please no! Some sort of timer? Aaaargh!

Closures (basically, anonymous inner functions, which retain the surrounding context) really help fix this. Additionally, I made the synchronous/asynchronous choice completely optional, by just adding an optional callback parameter to the generic SOAP call. Here's some of the reworked code (actually, this is nearly all of the rework right here).

The only wrinkle I'm eliding below is error handling. Instead of throwing, I construct an error object, and pass it back; below we can see the caller check for one of these.


function SOAPCall(sReq,sURL,pObject,fnCallback)
{
var HTTP = CreateObject("Msxml2.XMLHTTP.5.0");
if( fnCallback )
{
HTTP.open( sReq, sURL, true /* asynchronous */ );
HTTP.onreadystatechange = function()
{
// We're in an anonymous function, which will be called sometime
// by some COM thing, but we still know what "HTTP" means
// because it's in the scope in which this function is declared
// - we're in a closure
if( HTTP.readyState!=4 ) return;
fnCallback( parsed( HTTP.responseXML ) );
};
}
else
{
HTTP.open( sReq, sURL, false /* synchronous */ );
}
HTTP.setRequestHeader( "SOAPAction", theAction );
// ... build the message, then HTTP.send()
if( fnCallback )
{
// No need to return anything, the call is happening in background
}
else
{
return parsed( HTTP.responseXML );
}
}

And the caller...

var mydiv = // something local
var f = new g.GrooveFileDescriptor();
f.SetName( sFileName );
pFilesToolData.ReadFile( f, function( pStream )
{
if( IsError( pStream ) )
{
// That's not a stream, it's an Error...
}
// use the stream (here, the contents of a text file)
mydiv.innerText = pStream.ReadText();
pStream.Close();
} );

The callback is declared inline -- literally, as the second parameter to the .ReadFile call -- and it's a closure.

---

For comparison...

  • Using the Mozilla SOAP API shows pretty much this exact thing (If only I'd seen it beforehand!). They don't talk about the way JavaScript closures make this really powerful, though.
  • Remote Scripting (which I hadn't heard of before) can call server functions asynchronously from a Web page; this uses a helper object which gives you wait() and cancel() methods.
  • The corresponding C# technique (described in Using Delegates Asynchronously by Richard Blewett) is very general, but looks like slightly more work.

July 11, 2003

(No picture)

Via Tim Bray, a conversation with Jim Gray:

Clear your schedule, because once you've started reading this interview, you won't be able to put it down until you've finished it.

Who would ever, in this time of the greatest interconnectivity in human history, go back to shipping bytes around via snail mail as a preferred means of data transfer? (Really, just what type of throughput does the USPS offer?)

Yesterday evening - looking out over the beautiful Seattle waterfront - I had exactly the same conversation with a friendly retired couple who asked me how I managed to be on the net, sitting on a downtown bench. We got to talking about digital pictures -- I'd left my camera at home -- and agreed that the only sensible way to ship lots of pictures around was by post.

We'll fix that one sometime soon, right?

But, as the saying goes, never underestimate the bandwidth of a truck full of DVDs...

July 05, 2003

Component models

Bill de hÓra: Foundations for component and service models:

The core problem of component and service architectures is easy to express: how do I change a published interface without breaking the callers?

...Use highly generic method calls that are qualified with metadata - this is how SMTP and HTTP work and is often cited as a reason for their phenomenal success. You'll notice that these are the polar opposite of models such as the EJB spec, which actively encourage you to pile on the methods and go n^2.

Mostly to bolster my argument for a four-method API to GWS (of which more sometime)...

Innovation and Conformity in a Microsoft World

Bookmark to watch sometime soon: video, abstract. Douglas Crockford of the enigmatic Faceless Corp..

Innovation

Innovation by users. Some good stuff here.

Empirical research is finding that users rather than manufacturers are the actual developers of many or most new products and services – and that they are a major locus of innovative activity in the economy. This finding opens up new questions and avenues for exploration in fields ranging from economics to management of technology to organizational behaviour to marketing research. Examples are patterns in innovation by users, characteristics of innovating users, design of a user-centered innovation process, economics of a distributed innovation process that includes users as innovators, and social welfare implications of innovations by users.
(via machinelake)

WSS webparts

At SPSFAQ: SharePoint V2 web parts in five easy-ish steps.

CSS slant tricks

Slants: "It's a hack. A trick. It is a way to make pure HTML and CSS draw something that is neither vertical nor horizontal". Check out the Amazing Rotating Box.

(via Pete Cole)

July 02, 2003

Groove Files Preview Gem

Paresh describes a neat way to use the Groove files tool to store and browse offline web pages. Seth and Paresh showed me yesterday: it's surprisingly useful.

Daniel, I think you were looking for this-and-a-bit-more (something more like SurfSaver-on-Groove). Here's one version of the full recipe:

  • Have a bookmarklet, explorer bar or something (waffle waffle!)
  • which saves the current webpage and images to a temp folder, then
  • makes a local SOAP call to Groove, pushing the temp files into a Files tool, and
  • optionally, lets you jump there from the browser.
Something like that, anyway. (Plus search?)