I feel that I'm just not doing a good job as a Dad unless I blog about my kids now and then. For those far flung, here's a set of recents.
It's impossible to resist giggling along with this one of Nolan laughing hysterically at the frog blowing in his face
And representing for the Badgers in the apron Grandma sent, here's Gideon drawing with his markers.
A few family shots.
My favorite people in the world.
Gideon demonstrating the laws of physics.
Nolan, grinning as always.
Yours truly making sushi. We found a good deal on some yellow fin, but had to make due with sub standard, non-sushi rice -- which explains the look on my face.
One of Gideon's favorite video games is "Photoshop." He picks out the colors and the brush. Then I hold down the mouse button of a laptop while he moves his finger around on the track pad to do the drawing. Tons of fun!
Monday, December 29, 2008
Gratuitous family media
Posted by Eric at 9:39 PM 2 comments
Tuesday, December 16, 2008
Bailout your bicycle
If there's a silver lining to the $700 billion bailout it's legislation about giving bicyclists a tax break.
As a year round commuter facing sub-zero temps and snow this week, I was excited to see this news. Really, $20 / month doesn't cover a whole lot in bicycle expenses, but hey, I still think it's great news.
Posted by Eric at 8:41 AM 1 comments
Tuesday, September 02, 2008
Prophecy? Europe?
Oh yes, Europe and prophecy go together more than you might think.
This Sunday, September 7th, 2008, if you happen to be within ear-shot of Fort Collins, you should consider checking out a lecture about the role of Europe in light of Biblical prophecy. Norbert Link will be presenting a message that I think is significant in the scope of world history. I'm not even exaggerating.
By connecting the evidence of current events and secular history with prophecy, the news reported today from around the world becomes absolutely magnified in significance. I don't know all of the details about the content of the lecture, but I do know that you can expect to hear about the prophetic emergence of the European Union to global power. Right now, the EU is in its infancy and might not seem like a global super power, but I believe it will be. Power has already begun to shift in significant ways. Merely seeing that the Euro is gaining greater influence as the currency of choice in international trade, because of the instability of the dollar, with increasing momentum is an indication of the power shift. I'm not an expert economist, nor am I informed of all the intricacies of global politics, but it doesn't take much to notice that the EU is gaining influence quickly. As the EU becomes more organized and better at making decisions, they will become more powerful. And, by joining so many disparate peoples and populations, the European Union will become the statue with feet of iron and clay mentioned in Daniel 2. At least, that's what I believe the Bible teaches.
You'll also likely hear something interesting about the removal of blessings from the United States and United Kingdom. Essentially, the premise is that these countries are the inheritors of the birthright from Jacob in Genesis 48, becoming a "great people" and "multitude of nations" respectively. Of course, since it is a lecture about the teachings of the Bible, you may hear about the many reasons why these birthright blessings are being withdrawn as well.
Ultimately, the shift in global power we're seeing right now is all part of the plan that the Bible records. And that's a good thing. However, what's shocking is that it doesn't take much imagination fill in the gaps between current events and Revelation events.
What you won't hear will be requests for money, a devotional altar call, nor a feel-good "just love the Lord" message. It will be a much more sobering set of content. What you will hear, even if you don't agree with it all, is an observation and analysis of current events and history that will blow your mind, if you take the Bible seriously.
I challenge you to open your mind and check it out.
Posted by Eric at 11:38 PM 2 comments
Tuesday, June 10, 2008
...and Baby Makes Four
About three weeks ago my wife, Shana and I arrived home carrying our newborn baby boy Nolan from the hospital. This is certainly a long overdue post, but bringing a newborn into the household tends to force some re-prioritization. Blogging fell pretty far down the list. So, without further adieu, a photo or 2. Introducing, Nolan.
I also figured that this would be a good place to record some of the details. At least before I forget them.
Over the weekend of May 17-18th, Shana noticed some different activity going on in her body. She had plenty of Braxton-Hicks contractions throughout the pregnancy, and what she was feeling was definitely more serious. So, I managed to scramble getting some things together Friday night, expecting that we might have to make a quick getaway. That was not the case. Things settled down completely. But we were warned.
Monday (May 19th) morning we woke up, and almost immediately became aware that we were going to be parents to a new child that day. The real contractions were regular and definitely stopped Shana in her tracks once in a while. To make things more interesting, I had an appointment with a recruiter that morning to talk about my job search -- I had actively started looking for a new job a week earlier and needed to find something fast. With things relatively stable at home, I figured that I'd take a calculated risk and go to the meeting. While Shana was at home, in labor, I was sitting at a coffee shop waiting very impatiently for the recruiter to show up. After ten looooooong minutes, and no show by the recruiter (communication mix up) I decided to leave. I'm glad I did.
I got home around 10:30 am and called up Shana's brother, Robb, to arrange a pickup for our two year old, Gideon. He stopped by around 11 am and picked him up, to deliver to Granny and Papa. Everything was pretty well under control at that point.
Contractions were still relatively mild, so in order to encourage them along, we decided to go for a walk around the neighborhood. It certainly worked. When we arrived back home an hour later, Shana was having contractions anywhere from 5 to 6 minutes apart. Right on track.
Our plan was to allow Shana to labor as much as possible in the comfort of our home before arriving at the hospital for the delivery. We had been through it once before, taking Bradley method classes, so we had a pretty good idea of what to do. Shana immediately laid down to get some much needed rest while the contractions did their work. I think she may have even gotten a little bit of sleep.
While she was resting and allowing labor to naturally progress, I was tediously filling out a job application, hunting down history and contact information. I had a potential job offer in the works, and didn't want to take too long to respond. I'm sure they would have been understanding about any delays, but to me it was baggage that I could clear from my head. It also gave me something to do as an outlet for all the nervous energy. So, I did as much as I could, and kept as much job seeking momentum as I could.
Around 3 pm, while I was doing some scanning, Shana mentioned, in a tone that could not be ignored, that she was going to need some attention soon. Scanning could wait.
From that point on, things happened pretty rapidly. She was struggling to find the most comfortable position to be in while the contractions strengthened. Hands and knees? Nope. Sitting on a therapy ball at the end of the bed? Nope. Kneeling on the floor, resting on the bed? Nope. The most comfortable position wound up being a side-lying position on the bed. Good enough for me. I tended to her, trying to massage as much as I could to relieve the pressure. I then called the midwives to let them know that we were in active labor and that they could expect to see us later that day.
Continuing to labor, more intense, deep moaning turns out to be unbelievably helpful for Shana. In the back of my head, I was thinking to myself that the first time we had a baby, the moaning was quickly followed with pushing -- hmmmm. Time to pay close attention. Shana, to her credit, was extremely well composed, especially in retrospect. She looked relaxed, and there was no screaming in pain, but she was definitely working pretty hard. Cool towels were what she needed most. At that point, contractions were anywhere from 5 minutes to 3 minutes apart.
4:00 pm. Shana and I decide that it's time to start moving to the car to get to the hospital for the delivery. I call the midwives to let them know we're on our way. While I'm on the phone, Shana cries out, "I feel like pushing!!!" I really didn't want to hear that. Both of us panic slightly because we KNOW that we stayed home too long. I call the midwives back. "Shana feels like pushing, we're going NOW!"
Then began our lengthy venture down the stairs. Wow, it took some time. Trying to convince a laboring woman, who feels like pushing that she needs to start moving down stairs is like, well, just what it sounds like. It took 30 minutes to get downstairs. And, about half way down, her water broke.
PANIC!
Her pitch rises in fear. In a moment of idiotic diplomacy, I ask her if she wants to ride in the car, or if I should call an ambulance. I definitely didn't need to burden her with something as serious as a decision. Anyway, while I scramble to grab all of our bags in my arm, she found enough strength to make it half way across the front yard before another contraction hits. Remember, she feels like pushing. I hold her up to support and notice that she's crossing her legs at the knee. I nearly freak out. OK, that one's over, let's get her in the car.
She manages to get into the car, but there's absolutely no way she's going to actually sit. She knelt on the front seat, butt towards the windshield, hugging the headrest, while I drove as swiftly as possible to the hospital.
12 minutes later, Shana hasn't given birth yet, and we arrive at the hospital emergency room meeting our midwife at the entrance. They get a gurney, and try to decide whether to deliver the baby in the emergency room or in the actual birthing room. Shana decides that she can make it to the birthing room. Good thing too. I don't get the impression that ER folks enjoy delivering babies.
Up the elevator we go, and get into the room at 4:49 pm. A push or two later, the midwife says, "I think he's coming on the next push." I am completely overwhelmed with emotion, laughing and crying at the same time, as I watch our son Nolan gracefully enter the world. At 4:53 pm.
9lbs 8 oz, 20.5 inches long. Not chump change!
Postscript:
The following day, Tuesday, I managed to get some paperwork faxed to an employer, and by lunch time, I had a favorable job offer from them. What an absolute amazing 24 hours.
Posted by Eric at 11:51 PM 0 comments
Monday, April 21, 2008
Multi-threaded Socket Server in Java
I have always been curious about how to make a multi-threaded server in Java, and it turns out to be pretty simple to get something basic up and running.
My goal was to create a program that would listen for incoming connections from a client, and repeat whatever is sent to that server. You can see this server work using a telnet session on port 5000.
telnet localhost 5000
Then, whatever you type will be echoed back to you. If you want to quit, just type exit.
Here's the code, consisting of 2 classes.
package sockets;
import java.io.*;
import java.net.*;
/**
* Includes main method to get things going
* Otherwise, this just prepares a new ServerSocket that
* listens for new connections
* and starts a new thread for each connection
*/
public class EchoServer {
public void go(){
try{
ServerSocket serverSocket = new ServerSocket(5000);
while(true){
System.out.print("Listening for connections on port 5000... ");
Socket client = serverSocket.accept();
Thread t = new Thread(new EchoClientHandler(client));
t.start();
System.out.println("Connected - "+client.getInetAddress());
}
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] args) {
EchoServer server = new EchoServer();
server.go();
}
}
/**
* The Runnable job that takes in the new Socket
*/
class EchoClientHandler implements Runnable{
private final BufferedReader reader;
private final PrintWriter output;
private final Socket socket;
private static final String MESSAGE = "ECHO... [?]\r\n";
private static final String EXIT_MESSAGE = "Sad to see you go. Goodbye.\r\n";
private static final String WELCOME_MESSAGE = "Welcome to the Echo Server. Type something to see it echoed back to you!\r\n";
public EchoClientHandler(Socket incomingSocket) throws IOException{
socket = incomingSocket;
output = new PrintWriter(incomingSocket.getOutputStream());
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
public void run(){
try{
output.write(WELCOME_MESSAGE);
output.flush();
String line = null;
while((line = reader.readLine()) != null){
boolean quit = false;
output.write(MESSAGE.replaceAll("\\?", line));
if(line.trim().equalsIgnoreCase("exit")){
output.write(EXIT_MESSAGE);
quit = true;
}
output.flush();
if(quit){
break;
}
}
}catch(Exception e){
System.err.println("OUCH! "+e.getMessage());
}finally{
try{socket.close();}catch(Exception ee){}
}
}
}
Here's how it works.
When the EchoServer starts up, it opens a server socket that listens for incoming connection requests. When it gets a request, it creates a new handler instance, taking the Socket as an argument. The handler is a Runnable class, and used to start a new Thread. The result is that the EchoServer can handle more than one connection at a time -- just like a good socket server should.
To expand on this, it would be a good idea to implement some means of managing the threads and connections. Using the java.util.concurrent API would be a good thing to do to implement some means of thread pooling in the server instead of using naked Threads. Thread pooling is an important thing to implement because each new persistent connection requires a new thread. Too many connections would cause some real resource problems. However, if there are limits to the amount of connections the server will allow, you need to manage connections. Therefore, some intelligence might need to be added to a Client program, so that a connection need only stay alive for a certain amount of time before becoming disconnected. Then, a well designed client might seamlessly create a new connection to the server.
Posted by Eric at 10:03 AM 1 comments
Labels: Java
Thursday, April 03, 2008
Social Networks are the Next Commodity
When I need to fly I typically treat myself to a copy of the Economist. In my opinion, it's got some of the best news available in the world. Last week, on a trip to San Diego, I picked up a copy for myself to enjoy.
The March 22 issue had an interesting and compelling article about the future of social networking sites. Essentially, the premises state that social networking is something that will become pervasive and a feature that people come to expect on a site. There's no question that social networking is becoming ubiquitous. You could make the argument that social networks are already a commodity, in the way that because they are everywhere, and cheap or most likely free to participate in, social networking is already a commodity.
OK, what does that mean? It means that the only way to make any money on a primarily social networking platform is to increase volume. Indeed, it's the page views, not the amazing amounts of revenue that make Facebook so highly valued. What I found interesting about the article in the Economist was the part that mentioned how difficult it is to create any sort of solid revenue model based on the high-traffic, social network, advertising only business model. There are some serious limits to the amount of money a business can make with this kind of structure. And it gets worse. Since most social networks don't to anything more useful than poke, attack, or leave a message on a page for a friend, there's not much value for a user to remain loyal to a site he or she is a member of. That means declining page views once the buzz is gone. You can see attempts to maintain buzz by sites like myspace and linkedin constantly adding new features, but in the end, it just makes for a more complicated we application, with a diluted purpose.
So, what's next?
Email for one. The fore-mentioned article makes a point of explaining that email is the best way to really build a rich social network for the sake of networking. That's right, email is the next killer app. Check out Xobni. They're building what I believe is a real and genuine social networking app with purpose. And they integrate it with your email client. I also expect that we'll see some pretty amazing things, with some genuine utility, hitting our mobile phones very soon. When I mention utility, I'm not talking about ridiculous pillow fights or zombie attacks either. With the android platform, and the iPhone SDK, developing real social networking applications that tie into real people doing real things in real time becomes much more of a possibility.
What about social networking sites? I believe that we'll see somewhat of a shake down in the realm of social networks. They will be on plenty of sites, and the smart ones will use some means of identity sharing between them. However, I believe that the social networking destinations will need something of real value to offer their users. Otherwise, with nothing invested, and nothing returned, there's not much reason to build a profile. Eventually, social networking will become the byproduct of something more useful.
Posted by Eric at 12:54 PM 1 comments
Thursday, February 07, 2008
February New Technology Meetup - Boulder
Tuesday, I had the opportunity to present one of the sites I've been working on in the past year - ReferenceVault. I was trying to break the record for the number of slides presented in the span of time I had. In 5 minutes, I went through 54 slides, and did a 90 second demo of the site. Pretty fun.
Here's a picture of me requesting a reference captured by one of the BrightKite guys.
Posted by Eric at 10:14 AM 0 comments
Labels: Boulder, ReferenceVault
Tuesday, January 22, 2008
Leopard for the Web Developer - Running Tomcat as a Service
In my experimentation with configuring multiple virtualhosts with SSL, I stumbled upon the magic of launchd within mac os x. I use it to make a call to ifconfig when I start up to create a new loopback interface, and it works splendidly. Knowing that it would work on startup, I thought I'd apply the principles to Tomcat.
The process of setting up Tomcat as a service in Leopard is extremely simple. It goes something like this:
- Download Tomcat
- Unpack Tomcat where you want it (/usr/local/tomcat is a good spot)
- Create a lauchd plist configuration to point to the tomcat executable
- Place that configuration file someplace where launchd will find it.
- invoke launchdctl to install the new service
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Disabled</key>
<false/>
<key>EnvironmentVariables</key>
<dict>
<key>JAVA_HOME</key>
<string>/System/Library/Frameworks/JavaVM.framework/Home</string>
</dict>
<key>Label</key>
<string>org.apache.tomcat.tomcat6</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/tomcat6/bin/catalina.sh</string>
<string>run</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>ServiceDescription</key>
<string>Tomcat 6 Server</string>
</dict>
</plist>
OK, here's what's happening. The plist defines a dictionary data structure instructing launchd how it should work. You'll see a <key> followed by a value of some sort. I'll go key by key.
- Disabled - a boolean value.
If you want to have this active, set the value to false, as it is here. If you want to disable the service without uninstalling it, just change the disabled value to true. - EnvironmentVariables - a (sub)dictionary value.
This is just a set of name value pairs defining environment variables that you might need. In our case, Tomcat needs to know what JAVA_HOME is. You can set more if you want by adding more <key> and <string> pairs - Label - a String value.
This one is really important. It needs to be a unique identifier for the launchd process. launchd keeps track of all the things it starts and stops with this Label value. Just make sure that it's unique. It's common practice to use the reverse-domain syntax that you see here (org.apache.tomcat.tomcat6). Incidentally, it's also common practice to name this plist file with the same label (org.apache.tomcat.tomcat6.plist) - ProgramArguments - an array of strings.
Think of this as what you would type at the command line. Basically, anything you can do at the command line can be placed in a ProgramArguments value. The first string in the array is the executable program that you wish to run. Anything following is an argument that you would pass to that command. In our case, this merely does the following command:/usr/local/tomcat6/bin/catalina.sh run
- RunAtLoad - boolean value.
This is what makes this a service, telling OS X that this should run when starting up. - ServiceDescription - String value.
This helps in the console to figure out what's running. It should just be some sort of description identifying the process. In this case, Tomcat 6 Server.
Launchd looks in a couple of places for these kinds of configuration files. From the man pages of launchd:
~/Library/LaunchAgents Per-user agents provided by the user.
/Library/LaunchAgents Per-user agents provided by the administrator.
/Library/LaunchDaemons System wide daemons provided by the administrator.
/System/Library/LaunchAgents Mac OS X Per-user agents.
/System/Library/LaunchDaemons Mac OS X System wide daemons.
Since I want tomcat to start up as a machine process, not a user one, I place it in /Library/LaunchDaemons. If I wanted to make it a user process, I put it in ~/Library/LaunchAgents. A couple notes about this. First, if you put your file in /Library/LaunchDaemons, the plist file needs to be owned by root. The easiest way to do this is to open Terminal and do a "sudo cp org.apache.tomcat.tomcat6.plist /Library/LaunchDaemons/". This will make root own the file so it can start up as a system process. Second, if you decide to place the file in ~/Library/LaunchAgents, you don't need root ownership, but you do need to make sure the directory exists. By default, Leopard does not have a "LaunchAgents" folder in the user Library. So, you might have to make that directory before you copy your file there.
Final step, you'll need the Terminal. It's install time.
If you placed the plist in /Library/LaunchDaemons, do this
sudo launchctl load /Library/LaunchDaemons/org.apache.tomcat.tomcat6.plist
If you placed the plist in ~/Library/LaunchAgents, do this
launchctl load ~/Library/LaunchAgents/org.apache.tomcat.tomcat6.plist
That should do it. You now have Tomcat installed as a service on Leopard.
Friday, January 18, 2008
JSON Recursion -- Making a Self Reference
I have been working on a simple JSON library in Java which will allow me to serialize a JSON string. I'm pretty satisfied with the results so far, and I intend to release the code, however, until today, there was one thing that threw me for a loop. Writing JSON including a self reference. Here's the problem
When you write the following JSON syntax:
{"me":this}
You expect that when you access the 'me' property, it would give a reference to that object. However, what you get instead is a reference to the Window object. This happens because the closures that javascript has assigns the 'this' to the Window because during the construction of the new object, the new object doesn't yet exist, and 'this' still refers to the Window. Not what we wanted.
Here's the fix:
{
"me":function(){
this.me = this;
return this;
}
}.me()
Instead of assigning the 'me' attribute to 'this' right away, we construct the object, setting the 'me' attribute to a function. The 'me' function re-assigns its own value, and in effect, kind of self-destructs. Finally, we make the 'me' function return a reference to 'this'. 'me' is now assigned a reference to itself.
This method works within an eval as well. It also nests pretty well too. Here's a more complicated example, with a sub-object containing a self reference, as well as multiple self-references:
{
"me":function(){this.me = this; return this;},
"alsoMe":function(){this.alsoMe = this; return this;},
"subObject":{
"subMe":function(){this.subMe = this; return this;}
}.subMe()
}.me().alsoMe()
Posted by Eric at 2:24 PM 1 comments
Labels: Java, javascript, json