Thursday, July 31, 2003

Transfiguration! It must be the ice cream!

tranfiguration
You excel at Transfiguration. One of the most
dificult classes, you seem to be a natural at
turning a coke bottle into a homework pass.


Which Class at Hogwarts Would You Excel at?
brought to you by Quizilla

Mood: amused
Music: Bad Religion - Sorrow

Tuesday, July 29, 2003

UT2003

In my earlier update, I promised to talk a bit about UT2K3... and completely forgot to do so. Here are my views:


The Unreal Engine renders beautiful scenery, although I had to turn some visual details down to get a consistently high framerate (on my P4 1.6ghz, 512mb RAM, GeForce 4 Ti 4200 128mb). Some of the levels are really, really pretty - and really pretty big! The Unreal engine's handling of outdoor areas continued to impress, although it is still obvious that tricks are used to ensure that you can never see too far away (occlusion culling keeping framerates high); on the few levels where this isn't the case, framerate stutters. Sound quality is crisp (despite awful voice acting!), especially the music which is excellent (the intro music really made me want to play Deus Ex!). Control is reasonably sharp, but has the 'slightly squishy' feel that dogged Unreal 2 (but not the original UT); it is less like QuakeWorld's fast turns and tight air control, which is more realistic but also more frustrating.


The game itself is a mixed bag. Double domination (like Domination from the original UT, but tweaked) and Bombing Run (basically rugby with guns; it reminds me a lot of Urban Brawl from Shadowrun!) are both great, CTF is decent, and deathmatch isn't bad - but the squishy controls prevent it from feeling great. The instant action mode is nice. League play feels like a bad attempt to squash EA Games style management into an FPS; if the bot personalities were a bit more differentiated, it might be worthwhile. As it is, they universally suck - so it really doesn't matter who is on your team. In one Bombing Run game, neither side's bots ever actually found the ball!


Map design is mixed. All the maps are beautiful, but there are fewer 'flavour' maps than in the original UT; no ships, flying fortresses, or low gravity maps (at least that I've found so far). Maps instead focus on being balanced. This leads to solid, predictable games; fun, but not as fun as flying around a low gravity parking lot!


Weapons are a very mixed bag. The bio-rifle is back (ugh). The flak-cannon has a slightly less spammy spread than the original UT, but is still nice. The shock rifle is about the same as before, albeit slower moving (MUCH easier to perform combos!). The sniper rifle has been replaced with the lightning gun, the single most stupid weapon ever: its zoom is slow, it has a recharge time, and it looks goofy. It also seems to require less precision than the old sniper rifle, while having a little lead time on firing. So you are more likely to hit, but less likely to get a headshot. Sadly, a lone sniper can no longer hold a base in CTF!


Overall, this game would be good for $20, but isn't worth full price. It is a really hard product to place; it is heavily tournament oriented, quite balance obsessed - but lacking much required skill to make yourself noticed (lots of spammy weapons, reduced emphasis on headshots!). Epic have announced that UT2004 is coming out - maybe it'll be better!
Mood: geeky
Music: Ozzy Osbourne: Crazy Train

Wednesday, July 23, 2003

*NIX

I learned a lot from SunOS at college, and Linux at home. I love FreeBSD to death. But surely there is something wrong when this is considered intuitive syntax:


find . -type f xargs sed -i.bak "s/oldtext/newtext/g"
Mood: busy
Music: Sisters of Mercy: I Was Wrong

Object Relational Mapping (again)

So my ORM system was conceptually validated again yesterday, when I implemented the 'ledger manager' part of the TSG Office Assistant. It was really nice to simply inherit an object that understands the basic database primitives required for business logic, and completely avoid writing SQL in the presentation layer. It isn't quite model/view - I didn't formalize it to that extent - but it is nicely stratified.


I did some searching around for other object-relational systems for .NET, preferably a lot more advanced than mine - considering only free software (both as in beer and as in speech). I found two on SourceForge. NHybernate appears to be a dead project, largely because the designers tried to copy a mature Java project class-by-class, rather than realising that the .Net Framework and Java libs work very differently in some cases. It does serve as a great example of database-agnosticism, though. (Hibernate for Java appears to be a pretty impressive ORM system, although I think that I might get angry using it; it tries to abstract away all of the little databasey details such as when to cache and when to commit to disk!). A more promising contender - at least in that it is still alive - is OBJ.NET. This is based on OJB/Java, part of Apache. It exhibits some very nice design, including transactionality (with explicit commit), not saving until you mark an object as dirty, and cacheing. It also features some horrible database code (OLE.net only!), but the developers say this is due for fixing in a later release (it is still very pre-alpha). The XML mapping between tables and classes isn't bad, but it looks like it might add a bit more overhead than I would like. Definitely a project to watch!


This got me thinking about ORM in general. It seems to me that in a traditional n-tier system, several tiers are all struggling to gold-plate their job and take over - and fuzzy thinking has allowed this to happen. Looking at a typical 3-tier system:


  • The Database Tier handles storage. At this level, you want normalized data, formalized set theory to ensure referential integrity, pure storage worries (replication, etc.). You may also want triggers to help keep everything in order (not strictly necessary if you implement referential integrity correctly), and stored procedures to ease/speed-up data access. In other words, just storage and related worries. (This should itself be broken into physical and logical storage, since the two are separate; fortunately, the DBMS should worry about physical for you!).
  • Business Logic Tier. This tier typically needs code to talk to the database tier (preferably in an agnostic way in case the physical medium changes), code to talk to applications, and lots of objects encapsulating business procedures. Lots of safety net code is a good idea here, too, since apps programmers can and will break things!
  • Application Tier. At this level, you worry about things like displaying data, having a user do stuff with it, and then sending the results back (via the business logic tier). Typically, you need a means of talking to the business logic tier, and lots of UI code.


The 3-tier model above makes a great deal of sense. It separates out three very different types of problem. So far, so good. Unfortunately, vendors just don't get it - and seem to be working pretty hard to make it easy to break this mold. For example:


  • Oracle can run fully-fledged Java in the DB server; they even advertise that the database can "help your business logic layer". Likewise, SQL Server will soon be able to host CLR programs. MySQL - barely an RDBMS anyway - can already run C code locally.
  • On the business-logic level, you need to resort to 3rd party items for truly seamless Object-Relational Mapping - or you need to waste scads of time writing plumbing on every project (in other words, the language vendors don't properly support the model they espouse, maybe because they want to sell bigger databases/database servers!). Worse yet, many business logic level applications become concerned with physical storage, particularly cacheing systems. Even worse - "object stores" designed to avoid having a relational database at all, save as a unit for storing BLOBs (binary large objects) holding serialized class data. You aren't going to get any benefit at all from your RDBMS if you don't let it do what its good at!
  • On the application level, the sins are countless. .NET offers some really nice platform agnostic data handling - and then plugs it directly into user interface objects! You can wrangle it to require separation, but I've seen so many projects - particularly ASP projects - that embed some of the business logic IN the display logic that it isn't even funny. (PHP, ASP and similar scripting langauges are particularly prone to this). Also, there needs to be a way to have the compiler shoot a programmer who needs a quick query from the database - but doesn't want to go through all the tiers to get it - and decides to embed a direct statement in the display logic.


All of the above problems can be avoided by avoiding fuzzy thinking, and applying some discipline to development. Everyone has made at least one of these errors (myself included), and it is really easy to make them over and over. Vendors screaming and shouting about their latest solution to a nonexistant problem (ie. a way to break a rational system by offering shortcuts) certainly don't help. (The general disdain for applying scientific method to business computing doesn't help, either!)

What seems to be needed is an easy way to create formally-correct tiers from a logically-correct data representation. Ideally, I would be able to create a logical representation of the data I wish to store - and it would be created in an RDBMS (with full integrity constraints), skeleton object mapping code would be created for the business logic tier, and an easy way to expose objects to apps would be presented to me. Oh, and if the database changes - as we add more requirements (reqs. are never static in the real world!), I want it to update the framework without (substantially) breaking higher levels of the system. I can do all of this with separate tools and much time/effort - why isn't there a one-stop-shop, yet? Am I asking too much?
Mood: restless
Music: Robert Plant - Tie Dye On The Highway

Tuesday, July 22, 2003

DSL Hell

Last night's Mage game was a lot of fun. Daffyd got drunk, and hit a 'mummy' over the back of the head with a beer-bottle... and lived. He even managed to make a vampire frenzy and eat another vampire. Quite a productive night!


Today has, thus far, been somewhat less useful. Our CenturyTel connection was flaking badly this morning. Received mail was working fine (it automagically uses the other connection as needed), but not being able to deliver to remote servers had the Charizard queue growing by several hundred messages an hour. Fun! Anyway, by the time I'd failed everything over to the Tranquility connection, CenturyTel were fine again. Grrr.


Anyway, I learned a bit from this. No matter how nice your automated ping-failure detection, sometimes errors don't show up in ping times. DNS-based failover is nifty - with the right TTLs, you can keep downtime down to minutes rather than hours; combine with MRTG graphs, and you can see success/failure in near-real-time, too. Nifty. Also, DNS_Balance, by Hiroshi Yukota is sweet. x.farm.tsghelp.com redirects to a copy of Balance, which dynamically replies with either of our connections based upon a simple text file. That file is trivial to update (I'm working on scripts to do it automatically), and traffic gets directed as needed. Nice and simple, and its in Ruby so no buffer overruns!


My TSG database programming continues apace. Last night, I validated by LightWeightList design - it is MUCH quicker than DataSets, which is good. I should have a somewhat-working prototype soon.


Also, SqWebmail is a great product - fast and lightweight, but butt ugly. My new mission is to make it look prettier!
Mood: hungry
Music: New Model Army - Ballad of Bodmin Pill

Sunday, July 20, 2003

.NET Framework 1.1

I upgraded the server to the 1.1 framework yesterday... and it looks like I have to go around switching off automatic validation of text boxes on projects on Monday. This blog is even a victim of an attempt to be overly helpful - everytime I try and include HTML formatting tags, the framework rejects it without even letting it reach my - perfectly safe - validation routines. Grrr.
Mood: geeky
Music: Inkubus Sukkubus: Wytches 2000

Friday, July 18, 2003

Conversations you can only have with Masons

Steve was chatting with some people from the Grand Lodge this morning about sprucing up their website. This is a Good Thing (TM), since it gets quite a bit of traffic and is starting to look a little dated. Anyway, one of the Lodge employees asks "So who did the Geocities pages we used to have?" We tell her. "Oh! He's going to die on Thursday, I'll talk to him then about removing them."
Steve and I sit in shock, the words WTF? floating above our heads.
Ceremonial death... apparently its a promotion. Phew!
Mood: bouncy
Music: Red Sky Coven - Home

Monday, July 14, 2003

Mystery!

One of our clients was broken into over the weekend: the front door lock was damaged (the police state that it appears to have been picked, which seems kinda odd for a double dead bolt!), the door to the server closet is lightly damaged (but was not opened - the thief didn't get in there, fortunately), all the workstations were powered up, seats and cushions were out of place. The really wierd thing: all the petty cash was still in place, there was no record of login attempts, no odd network traffic, and no apparent hardware changes (ie. no keyloggers inline, no visible network device additions). Very wierd. Who on Earth breaks into a rich charity, moves stuff around a bit, and leaves without touching anything?
Mood: confused
Music: Queen - Open Windows

Stupid Zip Library

The entirety of the missing field problem for the Masons turned out to be a brain-dead zip library that decided that a decent way to expand "50YrDate" was "_x0035_YrDate". Duh.
Mood: accomplished
Music: Incubus Succubus: Witch of Berkeley

Thursday, July 10, 2003

Updated twiglets

So I just called the Student Loans Company. They had lost my address, lost any record of my deferral, and lost the fact that I don't live in the UK! Anyway, the bulk of my loan is now deferred once more. Stupid, stupid people!
Mood: working
Music: Dio: Throw Away Children

The twiglet zone!

(For non-UK readers, "Twiglets" are a long, thin pretzel, most notable for tasting of sawdust and repelling the Undead.)


The last 12 hours or so have been strange. After sweltering my way through a long day in an un-airconditioned office, I headed to Sonic with Kris. Last time I ate at Sonic I was really sick - so this time I avoided anything cheese-like, and survived! Pancake on a stick is definitely an oddity - take a regular sausage, wrap pancake around it, and deep-fry; the result is then dipped in syrup. Whacky, but tasty.


After Sonic, we headed to Wal-Mart, bought some acrylic paint, and headed out to John's house to paint Warhammer figures. On the way, the Red Peril (Kris' cellphone) goes off - and Eric "Gustav" Johnson is on the line! He went missing three years ago, and had been successfully avoiding every effort at finding him - and now he's back in circulation, and on his way to CoMo! So, we sat down and painted figures - my Dark Angels don't suck quite as much as they could, but they are definitely testament to my failing eyesight. Ah well, at least they look angry! Kris did a really nice job on most of her Dark Eldar. Towards the end of the evening, she went off to find Gustav, and I went to bed.


Sleep was very poor: Boda the Hamster was at her noisiest, knocking stuff over, dancing, making her wheel squeak, etc. - definitely enough to keep me awake! On top of that, I never sleep well with strange people in the appartment; for some reason, my system just won't rest until the second or third time someone has slept over.


Around 8 this morning, my Mother called my cellphone to let me know that the Twiglet Zone has now encompassed Glasgow - or at least the Student Loans Company. Everyone's least favourite quango has apparently completely forgotten that I have an address (to which they have written many times, and from which I have responded many times!), and instead decided to send mail to my mother - even though noone ever gave them her name, let alone her address! For some reason, they are sending me a collection letter - even though I filled in my deferral forms, etc. Wankers. I'll call them later today.
Mood: confused
Music: Incubus Succubus - Pagan Born

Saturday, July 5, 2003

Well, ick

Nothing ruins an evening more than a dead pet. I just found our elderly rat dead. She was just fine when we got back from Waynesville, too. Ugh.
Mood: sick
Music: None

Waynesville and Back, .Net Remoting

Well, I'm safely back from Waynesville. We left late Thursday night (11pm or so - after Kris finished class, giving us both time to talk to our other significant others online). The journey wasn't some bad: we dodged some deer, managed to stay awake (note for future reference: starbucks energy drinks are weaker than my normal coffee!) - so it wasn't too bad. We arrived exhausted, and pretty much went straight to bed.


Friday (July 4th) was a mixed bag. It was hot during the day, as well as being really humid - so we lurked and watched Buffy for much of the day. Kris' Mom took us out for Mexican early afternoon, and I really enjoyed a Mexican ommlette (it made me very full, too!). Later on, Judy came over and we ate ribs, chicken, coleslaw and beans. The food tasted great, but was really greasy - so I couldn't eat very much, and it repeated for much of the night! Judy was talking a lot about her online gaming/chatting habit; I was overcome by a sense of dread as she started talking about how someone else she new could "make emotes in chat". Poor Kris was bristling, ready for the strike even more than I was. Finally, she asks "can you emote?" Ignoring the temptation to demonstate how bad I am at drama emoting (although my face is stretchy!), I tried to narrow the scope. Eventually, it turns out that in Yahoo! chat there is a method of emoting (that is, producing text along the lines of "Herbert strangles the stupid end user"), but it confuses Judy. Judy complained that when she examined it it was all gobbledegook, with thinks like "left bracket font right bracket some text left bracket" - stuff, and I quote, that nobody can read. (I write this in raw HTML, for the record!) :-)


Anyway, our brush with end users and an overdose of food hadn't left Kris or I in the greatest of moods. After more Buffy (waiting for darkness), we headed out to Rittle Bridge to set off fireworks. Kris's Mom brought along a lawn chair, and things should have been great... in fact, they started out pretty well, with lots of neat explosions, pretty lights and similar. Unfortunately, people started showing up - first a Sheriff (who was really nice!), and then some people making drug deals. Not good! We headed for the hills - and ended up in Walmart. As Kris pointed out in her blog, long periods of time in Wal-Mart are bad for me. General Waynesville-inspired-twitchiness, repeating food, horrid Wal-Mart light and an alarm that kept going off had me pretty close to the end of my tether. Nobody died, but I'm sure that I wasn't great company. :-(


After Wal-Mart, we went home, and went to bed. I slept surprisingly well until about 8am, at which point the dogs made sleep difficult by getting excited about, well anything, really. Not long after we got up, we drove home - a nice, uneventful drive. After that: a nap!


This afternoon, I've been experimenting with some C# programming. My programming has had two focusses: .Net remoting using semi-persistent objects with a PostgreSQL back-end, and creating a Windows Service.


Remoting with PostgreSQL Persistance

I was really torn as to how to approach this, and there isn't as much literature around on the topic as I would have liked. Remoting itself is easy: you build a marshalling object, make it available as a channel (using TCP binary channels, since I don't need webservices) and ensure that any object I send over the wire is easily serializable - about 5 lines of code on the server-side, and 2 (more if you want to tweak options, particularly for performance) on the client. Really, really sweet! The difficulty comes with deciding how to persist data. The options I could see were: (a) simply stream objects to a datastore, (b) write objects that match the back-end with load/store/storenew methods per object, and (c) the Broker/Controller model in which I stream DataSet and similar data types with all logic controlled from a Broker object on the server side. There are advantages/disadvantages to all three. (a) suffers from versioning issues - if the objects change substantially between versions, I have to figure out how to get the data out of the old binary format and into the new one. Ick. Even with XML transforms, that sucks - so i didn't go that route! (c) is what I tried with the last incarnation of the TSG Office Assistant; it works very well, but it is ugly, and I'm not sure I like having to rewrite huge chunks of code when the storage-tier changes. Also, DataSets are heavy, and DataSet updating proved to be less reliable than one would like; so I'm not pursuing (c) this time around. (b) suffers from creating a lot of objects, leading to heap fragmentation - and potentially poor performance under some circumstances. It also lends itself to elegant code; I greatly prefer having classes for each data item derived from an abstract class (forcing me to implement GetID/Store/Load/StoreNew, and adding serialization automagically). This is also the most OOP approach. So far, performance is good, the code is elegant (although I dislike writing all of the INSERT/UPDATE/SELECT queries and parsing necessary!). I'm thinking of adding unit tests into the mix, as opposed to broad testing. More on that in another update, when I've tried it!


Windows Services in C#

I always hated writing services (that is, processes that show up in Admin Tools->Services) in MFC/C++ - it was clunky and horrible! .Net has streamlined this process a lot, although it still isn't as easy as I'd like. The Windows Service Wizard creates the basic structure very nicely, but it completely skips the need for an Installer class - leading to services that work but cannot be installed/used without additional programming. Fortunately, I found some tutorials (via Google) that helped me figure this out. It is also clunky having to install services via the command line, and then attach to them for debugging - but it could be worse. I guess having service installation/uninstallation in the GUI could cause more problems than its worse - getting rid of rogue services in the registry is no fun at all.


On the upside, a windows service makes a great remote channel host - and performance is noticably better than a console based server.
Mood: curious
Music: Incubus Succubus: Goblin Jig