Tuesday, February 16, 2010

Things I picked up at inside919.ning.com

So I went to the inside919 coffee meeting a few Tuesdays back and gleaned some ideas from Pat and the other attendees. I figured I would remind myself of them.

Pat discourages business cards, or rather the futzing around that inevitably follows from focusing on them. Not needed, except perhaps for other people to hand to others for you. Otherwise they waste your time. There are meaningful ways to connect with people; trading cards is not one of those ways.

What you should be after is building relationships. People tend to form opinions about you over a handful of interactions; Pat's suggestion is to be deliberate and form a strategy for making those interactions happen in a positive, but not an agenda driven manner. Send an anniversary card for the client's business. Deliver donuts and leave. Just show up, drop by with a hello. Send an email of a recent article or a newsletter with opt-in. Just help people.

Elevator speeches are for drawing in investors, but aren't really suitable for small business. Pat spoke of the ROI approach, which mirrors what I have seen in the dialog of others skilled at networking. The pattern

you know when (there is this obvious problem _____)? Well I (perform this function to address the problem _____)!
is one format suggested. Connect to the listener's problem-but only try to touch on one area, not everything you can do. People simply cannot handle the overload of explanation and will close down. You cannot convey information if the speaker is overwhelmed by the volume of details in what you say.

Also, leading off with a role-based description puts you in a pigeon-hole. Inviting people to form such conclusions about you before rapport is established, hinders your ability to establishes that rapport.

Most small businesses get income from a small geographic radius... 25 miles or so. And only about 100 clients - so as a small business a reasonable strategy is to work on getting the first couple of dozen clients. The theory is that if you can form customer relationships with that many people, your client network will build itself.

Tuesday, February 2, 2010

10 Ways to Make Drupal Die

I can't take credit for these, having overheard them at a Drupal Meetup in the area. While cleaning up my desktop, I found them in a text file of notes (I didn't have wi-fi access at the time.) These were classified as "Evil".
  1. Modularize the Synchronization of the Site with other Databases
    If you need to implement a synchronization process between the Drupal database and another distinctive codebase (CiviCRM?), don't do it as a module. In general, a module is a chunk of functionality, but it is invoked when a node is loaded that contains content of a type processed by the module. That just isn't the right flow for a cross-cutting operation like a site synchronization.
  2. Install untested modules
    How well did the developer test the module you're about to install? Try reading the reviews. If there aren't any, what makes you think it isn't a completely bogus piece of malware? That's unlikely with the community involvement Drupal has, but you've got to look at a lot of these modules as experimental until they've been well vetted.
  3. Hack the core
    Drupal allows extension in a separate set of site folders. Use them. Don't mangle the baseline of files in the standard folders. Changing the core files assures that you either (a) will neglect security updates or (b) will lose your extensions or (c) will crash your site with an "easy fix". Or all three. Any way, it is bad.
  4. Neglect a good update and security patching process
    Even if you don't run a site as popular as Slashdot, you cannot rely upon anonymity to protect your site against crackers. Drupal actually reminds you that new patches are available to apply to the core. But the correct process is to (a)Back Up (b) back out all of your add-on modules (c) Apply Patches (d) Re-install your add-on modules and (e) Back Up again. It can be really annoying to back out and re-enable all those modules, but understand that if you don't do things in the right order, you could potentially screw things up royally.
  5. Depend upon a module for a core feature, which you are not ready to support.
    Community modules may be free but can you get support? Think about what it means when even the original developer won't touch the code. When Drupal needs to be updated for a security patch, what do you do if your module is found to be incompatible?
  6. Bloat your system with lots of modules
    Under Drupal 6.x, it is often hard to deploy a meaningful feature without loading module upon module, and it can snowball. You can end up with so many modules that the number of database queries explodes, and responsiveness dies. If you are over a couple of dozen modules, you're in the kill zone. (A suggestion was to use the Watchdog module to profile queries.)
  7. Pull syndicated content into your database with custom modules.
    Consider a module that reads twitter feeds or scrapes atom/rdf published HTML newsletters. If the content and PHP code is not well designed and rigorously tested, such a module could do a lot of damage to the Drupal database, and kill your site.
  8. Allow a print-oriented firm to develop the site
    This is a somewhat biased viewpoint. Ford Motor Company uses sculptors to create conceptual designs for autos, but it takes a team of real engineer, not sculptors and marketing types, to do the engine and drive train work. To be capable of safe deployment of a Drupal site a company needs not only artists and marketing gurus, but skilled engineers. A marketing company without on-staff expertise may even be able to hide bad practices out of sheer luck, but ethical deployment of a Web CMS like Drupal requires a certain level of commitment to good engineering practices. What is the process for unit testing and performance profiling, revision/build management, source-code control, and digital asset management? What is their process for evaluation and updates when security patches are released? Or is the method just a "catch and release", with the client left holding a Drupal bag they're not prepared to maintain?
  9. Switch versions of MySQL and PHP without checking compatibility
    In particular it was observed that PHP 5.3 and Drupal 6 were incompatible. In engineering terms, we refer to this as "platform provisioning", the whole point of which is to avoid conflicts between components, and yep, it requires more testing. Good practitioners will have separate evaluation sites, and will use automation to hammer on the facility and sniff logs for problems.
  10. Use Views for search.
    This was out of the mouths of some of the more experienced Drupalers, who said that overextending the Views can actually trash the entire system. In response to a users' 49 word search, Views attempted tried a 49 way SQL "join". Trust me, that's a bad thing. They initially tried to limit the number of search terms, but ended up using a custom hook. Other suggestions were to use an external system like Apache Solr, or the Faceted Search module if the site is smaller than 10k nodes or so. Just don't use Views to do search.

Monday, February 1, 2010

Commenting on namespaces

James Clark commented on namespaces recently, (well, actually, it was last month.) I picked up on it in Robin Cover's newsletter. In the blog, Clark and a number of well known standards participants debate the mistakes that were made in the language architecture of the XML Namespaces rec.

One issue is that, if in a moment of inspiration I decide to invent an XML element name,
and at some time before or after my glorified creative moment, you also create a foo for your vocabulary, then who is to say that my foo is not the same as your foo? More to the point, if and when both of our foos are found in the same content, how are they to be distinguished for processing?

Of course, that's the main case behind XML Namespaces. The answer to the first question is, you say which foo is yours. That's where prefixes come in syntactically, and it is observed that significant complexity arises because programs don't actually get to work with the prefixes, but instead must work with projections of the prefixes onto URIs in the data model. The projection is not 1:1, but 1:many, so that a relation representing the mapping (prefixes onto uris) would not, in general, be invertible. Programs have to track a lot of state to juggle what is really going on when, for instance, nested elements reuse prefixes previously declared in the same document; or when script language instructions are embedded within attribute values, and they refer to namespace qualified names implicitly through a fixed prefix (syntactically a QName).

But what could avoid this state of affairs? Users of XML now routinely process multi-gigabyte sized content streams -- is it reasonable to expect a program to somehow know anything meaningful about all of the element names used in such a stream prior to adding a new fragment somewhere along the line? To me this implies a considerable amount of look-ahead, which is obviated by namespaces' allowance of just-in-time introduction of nested prefix declarations. On the other hand, a stream thus modified would have to go through a linear scan in order to determine all the namespaces to which it refers, instead of accessing, e.g. a header , catalog or external dictionary of some kind.

I faced an admittedly simpler problem of resolving part numbers from multiple suppliers. Actually, they were businesses our parent company had swallowed up in fire sales. The point is we had all kinds of identifiers that might look like one another. An experienced tech might tell by careful inspection, but they weren't designed to be distinct. Certainly a Web application couldn't tell the difference based on syntax (they were just numbers). The solution was to add a header to the payload, to specify the authority responsible for creating the identifier. I called it a "registration authority".

The registration authority was composed of a few pieces. The first piece gave the organization responsible for maintaining whatever registries there were. The second gave an abstract domain... in effect a semantic specification of the type of the identifier, with respect to the organization. The rest of the fields gave the domain-specific identifier, split into whatever fields it might contain.

My structure was not particularly original, except that it identified the registration authority and the domain it established, as a meta-object in its own right. This to me is the true underlying nature of an XML Namespace: it is a relation between the organization (the registration authority) and the abstract domain (the 'name space') for a given XML vocabulary.

One of the posters (John Cowan?) noted that in LMNL, they restricted namespace prefixes so that the relation is bijective across the entire document. Effectively, this ensures that the namespace relation is an invertible function no matter which element context you consider. This is terribly difficult to accomplish with indeterminate streams of markup content, since it requires complete knowledge of the prefixes used across the entire document instance "space".

Technically, the unique naming can be achieved by mangling of the prefix. For instance, any good markup API will computing ordinal numbers representing element positions, and no other element within the content will ever have precisely the same position. So users of very large streams could certainly ensure that no prefix was ever reused, and they need not look ahead to see what other prefixes might cause a conflict.But the element content would have to be mangled too, if it contained references to that prefix. I hope you can see where I'm going with this. It is a small step, and one I'm sure many developers have been doing for many years, to build a dictionary of functional mappings between the prefixes and the URIs.

So it doesn't appear insurmountable to require that the prefix-URI mapping be a function across the entire content, but it might make it considerably more difficult to compose fragments.