Gastronomicon

It's been a while since my last post, work has been keeping me fairly busy lately and my free time has been spent giving me a bit more time to have some time to myself.
On the brewing front, things have been quiet - the liqueur thing isn't really working out too well, I'm still having issues with the sharp nose on my spirits - but I'm still attributing that to the quad-stacked Turbo Yeast in my 100L wash... still trying to finish that one up so I can start stilling my normal recipe... expecting that to be a bit better.
When that has been wrapped up, I'll try my hand at some limoncello and macerations. Also on the agenda is putting some of my Ginger Beer into the fridge and giving that a taste test, as it's been almost six months since that was bottled.
The other big brewing plans I've been thinking about for a while is Cider. It's tasty, it's cheap and it's quite fashionable at the moment. Nobody I know has really done one though, so I've been a bit uncertain who I can bombard with little technical questions.
Ever lucky, my local brew store sent out an invitational for a Cider tasting and voting session for a new brew pub in West Perth, The Brown Fox. These guys have been open since March this year and have made their own wine and are moving onto brewing and selling their own Cider in the pub.
Unfortunately, due to a fat finger error when putting the event into my calendar - I missed the event and presentation by the owner on the technical side of making cider, not to mention the taste testing! Bugger.
Fortunately they had a really positive turnout and the owner, Greg, decided to invite those who were interested to come back for a monthly cider tasting/discussion at his venue. After a few quick emails, and several calendar reminders later - I attended my first monthly cider meeting.
Okay, so despite the big turnout at the first meeting - there was only four of us. Two of us were Cider newbies, so there was some really good discussion about cider making in general and some technical tips and tricks on getting the results you want.
Probably the biggest suprise was that the two cider brewers at the table both preferred brewing from store bought juice (preservative free, of course), rather than from the fruit themselves. Obviously there's a effort tradeoff there, but nobody seemed to think that there was any significant difference in the end product anyway.
So keeping that in mind, I'm keen to get my first Cider under way - hopefully as early as this weekend, assuming I can shuffle things around in my fermenters, maybe at a stretch to be ready for the next meeting, and maybe having something good to actually justify taking into work (yeah, right).
- Read more about Gastronomicon
- will's blog
- Log in or register to post comments
Runtime handler registration in .NET
I've been working on some home automation software in C# for a friend and hit a bit of a stumbling block the other day. I needed to be able to register some message handlers for this application at runtime.
To do this, one needs to use the reflection framework - this allows you to inspect the assembly types and metadata at runtime, and is useful for this type of thing. This isn't exactly rocket science, and one can quickly throw together a quick example to discover each of the types that implement a given Interface/Subclass and make a method call to a static method on the class:
// Find all the types in this AppDomain that implement the IMessage interface
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
{
foreach (Type type in assembly.GetTypes())
{
if( type.IsSubclassOf( typeof(MessageBase) ) )
{
MethodInfo method = type.GetMethod("ImplementsMessage");
MessageType msgType = (MessageType)method.Invoke(null, null);
_messageHandlers.Add(msgType, type);
Query the type and see what protocol message it handles
try
{
// If any bit of this fails, we'll fail silently which is OK
ConstructorInfo constructor = type.GetConstructor(new Type[0]);
IMessage obj = (IMessage)constructor.Invoke(new object[0]);
_messageHandlers.Add(obj.ImplementsMessage(), type);
}
catch
{
continue;
}
}
}
}
The above example will call the static ImplementsMessage method on each class that is discovered that is a subclass of MessageBase.
This is well and goodly, but the problems start when you try and declare the ImplementsMessage in either an Interface or superclass. In this case, I have an Interface IMessage that I want all message handlers to implement. Interfaces and base classes are good, as we know, for defining a concrete contract to ensure that all of our classes implement the methods expected of them by the rest of the code - and are a key part of the design of this library.
Unfortunately, in any of the .NET languages - you cannot define static members in an object being inherited. Whilst the CLR can handle this, it's a design decision made by the .NET team over at Microsoft to not support it in their languages, though it seems that this is one they're looking at changing.
OK. So we can't define a static method, which isn't nice and elegant - but surely we can drop the static constraint and use the above code? Well, err... perhaps
In .NET, the CLR transparently sends an object reference to every method call made. The obvious exceptions are calls to a constructor when instantiating a new method, and calls to static methods. So it's imperative in the case above that we can always instantiate the object before we call the ImplementsMessage method.
This seems well and good, until you realise that .NET does not guarantee a default constructor as used in the example above. No, really - it doesn't. This might sound contradictory to some people, as the C# compiler will automatically create one for you if you use it on a fully qualified type at compile-time, but not at runtime.
That means the above sample will only work in the case you have explicitly defined a sane default constructor on your class at compile time. This is bad because we can't enforce this implementation with inheritance - so we're in the same problem as before: programming by convention rather than contract.
Fortunately there's a solution, and it's nowhere near as long winded as the explanation up until now. I cheekily hinted at it at the start of the article, and the answer is Custom Attributes.
Attributes are metadata you can attach to structural objects in .NET assemblies that can be reflected at runtime. If you're doing .NET, you've used them without realising. They're used heavily by components to provide information for the Visual Studio designer, are used to assign versioning and copyright information to the final assembly files as well as many other places within the framework.
By creating a custom attribute class, you can mark your classes, structs, enumerations and the like with strongly typed data that is available at runtime. This sounds like an excellent solution to the problem at hand! Here's the custom attribute class I wrote along with the updated code fragment to register these types at runtime:
[AttributeUsage(AttributeTargets.Class,AllowMultiple= true,Inherited=false)]
public sealed class HandlesMessage : Attribute
{
readonly MessageType msgType;
public HandlesMessage( MessageType inType )
{
this.msgType = inType;
}
public MessageType HandledType
{
get
{
return this.msgType;
}
}
}
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
{
foreach (Type type in assembly.GetTypes())
{
if( type.IsSubclassOf( typeof(MessageBase) ) )
{
// Look for the attribute saying what message they handle
foreach (Attribute attr in type.GetCustomAttributes(false))
{
if (attr.GetType().Equals(typeof(HandlesMessage)))
{
HandlesMessage hAttr = (HandlesMessage)attr;
_messageHandlers.Add(hAttr.HandledType, type);
break;
}
}
}
}
}
And here's a message handler being tagged:
[HandlesMessage(MessageType.InterfaceConfiguration)]
public class InterfaceConfigurationMessage : MessageBase
{
// ...
}
And there you have it! It's a different paradigm, but still enforces the message to implement to the MessageBase contract as well as having to "register" to be picked up at runtime.
The message class itself will have to implement a few interface methods from IMessage to construct new objects, so in this case it's arguable that that might be just as valid a solution - but that has its own caveats.
For now, it's an elegant and simple way of registering message handlers in the application without relying on convention to ensure the message handler will behave as expected - and I've already had another opportunity to use custom attributes at my work to maintain backwards compatibility with some code that is being backported.
That's all for now - a more general update to come and no doubt some more C# and .NET examples too, as well as some iOS related items.
- Read more about Runtime handler registration in .NET
- will's blog
- Log in or register to post comments
Minitruth
Quick update on (mostly) non-brewing related stuff.
Video Streaming
After somehow missing that gstreamer XML pipelines have been deprecated, and after futile attempts several months ago to get them working - I had a chance to pick it up again and start trying to use the library directly.
It works really well either wrapped up with something like the CPAN wrapper for Perl (yeah, I know, I know) - or directly via C/++. Or, if you install the tools package, from the commandline (sheepish grin).
So for encoding and streaming stuff it works quite well, but is useless for transmission to the client (I was hoping for an end to end gstreamer solution for the sample project I was playing with) - so you still need something to repackage the stream into RTP/RTMP, as the gstreamer RTP stuff doesn't really cut it.
ffmpeg would make a good overall solution, and the ffmpeg server will repackage on the head end - but the overhead is higher than gstreamer's if you're generating multiple streams from the same source. You could get around this by writing a custom binary around ffmpeg perhaps. Food for thought.
Someone has suggested Wowza Media server is great for this type of deployment, as it does no encoding work but will repackage RTP/RTMP for clients - but the licensing prices are pretty abysmal - there should be an open source alternative... this isn't that interesting to me to go down that path though, and I think I've reached what I can reasonably do.
Storage Box
After a bit of a delay with changing jobs and making space for the rack in the garage - the storage box is up and running again. I haven't really had time to test the controller issues, it's been so inconvenient without it.
At least now it's sitting on a UPS and I've built the old array's disks into a RAID6 array for my personal docs, and presenting NFS to my VMWare server - which is a whole different story involving the disk controller in the x336 and VMWare's Linux driver interface. Basically, I'll get orders of magnitude better performance switching to it, and that makes me happy.
Brewing stuff
In the short time I'll have at home today, I'm hoping to blend together my liqueurs and get $partner to give me some more feedback.
I've also bought some mint to re-create the mint liqueur I did, after a leaky spirits bottle saw it empty itself all over the floor *sadface* I'll also throw on a chilli liqueur.
Also, instead of posting a list of things that I want to brew each post, I've put them on my wiki here:
http://wiki.autodeist.com/public:2brew
Some new additions however, which I think are worthy of a mention here:
Bee Pollen I saw a container of this at the shops today, really interesting stuff... but it contains enough natural sugars and whatnot - and apparently a few people have brewed it. So I'll give it a go and see how it goes... could be interesting.
Whey Wine After being tortured by final pictures of Shay's Milk Liqueur - I went on a bit of a Google to see if there were other Milk/Whey based drinks... the Whey Wine mentioned on Wikipedia seems worth a shot... again, could be interesting.
Software Messaging
Having been exposed to TIBCO's JMS implementation at work, a few of the things I've been rolling around in my head for a few years about software messaging and middleware are starting to make a bit more sense.
Whilst I've been looking at building a few fairly tightly coupled framework libraries - the idea of using generic messaging interfaces over a generic messaging bus makes things so much easier. When you're not rolling your own, you can also really leverage a lot of the 'solved-problems'.
To that end, I'm hoping to throw together a VM running Apache ActiveMQ - a different JMS implementation, and have a play around with that, but I have other code to bust out before I get to that.... it's kind of breathed new fire into a few projects that have been on the back burner though - keen to clear my plate and get cracking...
Which lastly takes me on to...
Work & Motivation
Without putting too fine a point on it, things are a lot better work-wise than they have been for a long time. Not being actively prevented from doing your job, and having meaningful and constructive work to do makes a huge difference - and it really helps you engage with the work that you do have going on.
... and being engaged means I'm starting to get back into the swing of things personally. Now I'm not spending my evenings recovering from a mental mind-fuck, I'm finding that I'm a lot more interested in the technical projects I've had on the backburner for a while now.
So things are good, and despite a shortage of sealed glass jars (hint, hint - to anyone reading who wants to offload any)... all is well. More updates to come!
- Read more about Minitruth
- will's blog
- Log in or register to post comments
Pages