Tuesday, June 5, 2012

Using Guava EventBus with Spring

Recently, I started working on VeloxMUD again. The time away has really given me a new perspective on the code. Usually, that perspective goes like this:
  • What the heck was I thinking?
The first thing I looked at was the code that handled connections for the MUD. There is a thread that waits on socket.accept() and then passes the Socket objects off to a handler service (injected by Spring). Although this isn't terrible, I thought I could improve it by using a Publish-Subscribe pattern to decouple the two.

I started my search with Observable and found that it wasn't going to fit. Although the Observer interface isn't bad, the need to derive from Observable wasn't going to work for me. My publisher (the "observable" object) already derived from Thread. And it seemed there had to be a better way.

I stumbled upon Guava's EventBus. Ah ha! This is what I need! But wait, where are all the publish-subscribe guts that I need to implement? Gone... Publishers post events of any arbitrary type, subscribers add a method (with any name) and a @Subscribe annotation. Done. Wow! This is observable done right!

Oops... one small problem. Most of the stuff that needs to register is created and managed by Spring. How do I register my subscribers without tackling all sorts of nasty lifecycle problems?

BeanPostProcessor comes to the rescue! We can provide custom bean-processing code to Spring. With the right piece of code, Spring can do all the necessary registration for us.

/*
 * EventBusPostProcessor.java
 * Author: Patrick Meade
 *
 * EventBusPostProcessor.java is hereby placed into the public domain.
 * Use it as you see fit, and entirely at your own risk.
 */

package com.example.spring.guava;

import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;

/**
 * EventBusPostProcessor registers Spring beans with EventBus. All beans
 * containing Guava's @Subscribe annotation are registered.
 * @author pmeade
 */
public class EventBusPostProcessor implements BeanPostProcessor
{
    private final Logger log = LoggerFactory.getLogger(this.getClass());
    
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName)
            throws BeansException
    {
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName)
            throws BeansException
    {
        // for each method in the bean
        Method[] methods = bean.getClass().getMethods();
        for(Method method : methods)
        {
            // check the annotations on that method
            Annotation[] annotations = method.getAnnotations();
            for(Annotation annotation : annotations)
            {
                // if it contains the Subscribe annotation
                if(annotation.annotationType().equals(Subscribe.class))
                {
                    // register it with the event bus
                    eventBus.register(bean);
                    log.trace("Bean {} containing method {} was subscribed to {}",
                        new Object[] {
                            beanName, method.getName(),
                            EventBus.class.getCanonicalName()
                        });
                    // we only need to register once
                    return bean;
                }
            }
        }
        
        return bean;
    }
    
    @Autowired
    private EventBus eventBus;
}

We add the following XML stanzas to Spring's application context:

<bean id="eventBus"
      class="com.google.common.eventbus.EventBus"/>
<bean id="eventBusPostProcessor"
      class="com.example.spring.guava.EventBusPostProcessor"/>

And it works! Spring registers every bean with a @Subscribe annotation.

2012-06-05 00:50:09,084 TRACE [main] com.example.spring.guava.EventBusPostProcessor (EventBusPostProcessor.java:64) - Bean connectionService containing method handleConnection was subscribed to com.google.common.eventbus.EventBus

Saturday, March 24, 2012

S3E1: Node Equation Review


This is just a quick review of the node equation idea. In the following circuit there is one unknown node potential, labeled . The device parameters are: , , V, V.


What is the unknown potential (in Volts)? 6.21

e = ((e-V1) / R1) + ((e+V2) / R2)

[1/R1 + 1/R2] * e = (V1 / R1) - (V2 / R2)
[R2 / (R1*R2) + R1 / (R1*R2)] * e = (V1 / R1) - (V2 / R2)

[R2 / (R1*R2) + R1 / (R1*R2)] = (R2+R1) / (R1*R2) = 0.00032563

e = ((V1 / R1) / 0.00032563) - ((V2 / R2) / 0.00032563)
e = ((5.0 / 6800) / 0.00032563)  - ((-7.2 / 5600) / 0.00032563)
e = (0.000735294 / 0.00032563) - (-0.001285714 / 0.00032563)
e = 2.258065903 + 3.948389276 = 6.206455179
e = 6.21 Volts

Sunday, March 18, 2012

VeloxMUD Mobile Authenticator

So I've been writing a MUD since Christmas Eve of 2011. Recently I took a two month break from the project to get some distance from the code, research some ideas in existing MUDs, etc.

This weekend I had a thought ... wouldn't it be neat if my MUD had a Mobile Authenticator similar to Blizzard's Battle.Net Mobile Authenticator?

So I wrote one: https://github.com/blinkdog/veloxmud-mobile-authenticator

The authentication code changes every 15 seconds...

Now I have to add the authentication routines to the MUD itself. I don't think that will be nearly as hard as futzing with the Android layout!

Saturday, March 17, 2012

Android Virtual Device on 64-bit Linux

So I was trying to create a new Android Virtual Device (AVD) and it didn't work...


So I did a quick search and found an article on anddev.org:
All right, I was able to figure out the problem. The short of it is that I was using 64-bit Linux and had not installed the ia32-libs package, so the mksdcard utility was not working correctly. After installing this package, I was able to complete the step of making a virtual device.
So I took the advice and ran this:
sudo apt-get install ia32-libs
And then I was able to make my AVD.

Just a second...

So I wanted my desktop clock in GNOME 3 to display seconds. I did a quick search and found an article on AskUbuntu.com:

Yes, run this command in a Terminal: 
gsettings set org.gnome.shell.clock show-seconds true 
And you can verify with: 
gsettings get org.gnome.shell.clock show-seconds

And it worked like a charm. My desktop clock is now displaying seconds.

Wednesday, March 14, 2012

S2E6: Modeling

Joe has a barn that is feet from his house. He needs to supply 1000 Watts at 240V to a resistive load at his barn from the 60Hz power line at his house. Note that the circuit from the house to the barn requires two lengths of the interconnecting wire. He proposes to use number AWG wire to connect his house to his barn. Number AWG copper wire has a resistance of per 1000 feet.


What is the total resistance (in Ohms) of the transmission line?

(190.0 / 1000) * 1.588 = 0.30 Ohms

What is the resistance (in Ohms) of Joe's load at his barn?

V=IR
240 = I * R

P=IV
1000=I*240
(1000/240) = I
I = (1000/240) = 4.17

240 = (1000/240) * R
240 / (1000/240) = R
R = 240 / (1000/240) = 240 / 4.17 = 57.6 Ohms

What is the voltage drop (in Volts) from the house to the load at the barn due to the resistance in Joe's transmission line?

V=IR
V = (4.17)*(0.30) = 1.25 Volts

1.25 Volts * 2 lengths of wire = 2.5 Volts