Search blog.co.uk

Archives for: February 2006

Dire Straits

by cc0028 @ 2006-02-28 - 21:04:19

Yes. Dire Straits. The group. Mark Knopfler. Dire Straits.

Honestly, you didn't really think I was in that much trouble, did you? No, I'm just listening to Dire Straits playing away in the CD-ROM as I type this. All work and no play makes Jack a dull boy, so I'm rewarding myself because I'm within inches of having my test application up and running on both servers in exactly the configuration I wanted from the start.

I'd almost forgotten how good Dire Straits could be. All my life I've been interested in what people call Classical music - misnomer though it is - but my interest in pop music came to an end as Flower Power gave way to Punk. So I missed Dire Straits in the 1970s. I missed the 1980s altogether, more or less, given that it included the breakup of my first marriage, a bout of clinical depression and a serious back injury. So it wasn't until 1989 that I really got to listen to their music.

At the time I was dating a girl whose taste in just about everything I still admire. She was a fan, if that's the word, of Dire Straits and made me listen; despite my protestations that I no longer had any interest in pop music. I was blown away, as they say. This is music quite as inventive as any serious music I've ever listened to.

But I still managed to live without it. I moved to Wales. The girl moved to Milton Keynes and thereby nearly shattered my illusions about her taste. Within a few short years I was re-married and Dire Straits were consigned to a short period of my history.

Then this Christmas as we drove to Sheffield to visit my mother, I saw a Dire Straits CD in the shop at the motorway services.

"Ew! Dwi'n hoff iawn o Dire Straits",

(Oh! I love Dire Straits)

I said, to my wife.

"What", she said, "I didn't know that. You've never said".

So we bought the CD and listened to it all the rest of the way up to Sheffield: and most of the way back down, as I recall.

Then, a couple of weeks ago, my brother-in-law made a compilation for me, and that's what I'm listening to now. Dire Straits.

What? The MSc? Oh that ...

The Linux side is all configured and working on Apache with an application server running as a daemon that starts automatically when the machine boots - as does Apache, of course. The Windows side is well on its way: the application server is working and the application itself is working in IIS for users on our LAN. The only thing left to do is to make the Windows application callable from outside of the LAN. We should be able to sort that out tomorrow or the day after.

The problem with Apache was that I was trying to configure Apache using an out-of-date version of mod_mono, the helper program that Apache uses to deal with ASP.NET pages. Once I'd persuaded Red Carpet to allow me to download the latest version, all I had to do was follow the instructions on the Mono Web pages. You can look at the application here if you want.

Red Carpet? I'll explain another time, if you remind me.

:)


 
 

Deploying a daemon

by cc0028 @ 2006-02-25 - 21:07:17

Sometimes you want your computer to run some process whether you are logged in or not. Let's say, for example, that you are hosting a database on your PC and that you want to be able to query it remotely whether or not anyone is logged in. It would be very inconvenient, wouldn't it, if you had to leave your private email exposed just because you wanted to give other computers access to the data stored in the database.

The way this service is provided on a computer with no-one logged in, is that the server - your database server in our example - listens on a network port. MySQL, the popular open source database, for example, listens by default on port 3306. Web servers, by default, listen on port 80.

I've explained before that ports in this sense are not physical objects. They are, if you like, the final part of an address to which messages are sent: the parts that determine which programs are waiting for which messages. So they are a bit like the name in a postal address.

So how can a programmer create a program that will behave in this way? After all you are asking a program to start without anyone (human) starting it and to keep running even when the last human has logged off: but not turned the computer off, obviously!

In the Windows world, programs like these are call "Services". Basically what happens is that the programmer fills in a sort of a template that conforms to certain conventions that Windows understands. The template provides methods for starting, stopping, restarting and pausing the service, amongst other things. So, for example, in the OnStart() method of the template a programmer can put code that sets up the action of listening on the chosen port.

A utility program like installutil is then used to install the completed template as a service, which can be configured from Windows Administrative Tools | Services. This tool allows you to choose things like whether to start the service automatically when the machine boots, and what login to use.

Unix and Linux have the less prosaically named daemons. Different flavours of Unix and Linux do things slightly differently, but the principals are the same. A script - a text file containing a program - is written that does pretty much the same sorts of things as the Windows template: but in the case of Unix/Linux, the script usually calls a service driver - a tool designed for the particular kind of service the programmer is trying to provide. In the case of Mono (.NET) programs, that driver is called mono-service. The script may also contain special comments that inform the operating system what the name of the service is, what other services it depends on and in what run levels it should be started.

Once the script is written, it can be tested from the command line. If it works, it can then be used to start up the daemon when required. Many systems now conform to the Linux Standard Base (LSB), which says that the script can be copied to the /etc/init.d directory. From that directory a special program like insserv can be called on the script. The program insserv is like the Windows installutil, in that it installs the daemon.

One difference between Windows and Unix/Linux is that Unix/Linux has a number of different run levels. For example you can start a Linux box in single user mode, which is run level 1; or you can go to a multi-user command line run level (3) or full GUI (5). The script the programmer writes says whether or not a daemon should be started in each of the available run levels. The other difference is that the programmer can stipulate that the daemon depends on the presence of other daemons. For example it is no use starting our database daemon that listens on a network port unless the network daemon (inetd) has already been started.

There are lots more choices under Unix/Linux. The price you pay for this, of course, is that life is just that little bit more complex as a result.

So why am I telling you all this? Well, you will remember perhaps that one of the problems I had outstanding was that I wasn't able to start my business logic remotely callable object via a daemon. I was having to use a server that was started manually and that would die when the person starting it logged out.

My other problem was that I couldn't get Apache configured to run ASP.NET applications properly.

The good news is that I succeeded in solving the daemon problem. So that one is cast out, as it were. The problem with Apache remains, though. I'm just hoping that someone on a mailing list will be able to help me out. If not, I'll just have to use XSP in standalone mode.

TMTOWTDI

by cc0028 @ 2006-02-24 - 22:24:16

Or at least that's what Perl programmers will tell you. It stands for, "There's more than one way to do it"; so I suppose I should be fairly pleased with how things have gone today. My Web application is up and running under Linux, and it's connecting to the remote business logic object and reading and writing data.

You may have sensed that I'm not exactly overjoyed. You're right. In order to reach this point, I've had to make a couple of compromises:

  • The remote object is being hosted in a server rather than a service
  • The application itself is being hosted on XSP rather than Apache

The first of these issues should be fairly easy to sort out. It's just a matter of being patient. The second is much more tricky.

The main problem is me, I think. I'm not a sysadmin by any stretch of the imagination. Sysadmin work is, unfortunately, anathema to me. I don't like it. So having to try to get to grips with the care and feeding of a complicated beast like an Apache Web server is not something that fills me full of enthusiasm.

It has to be done, however; and I haven't given up hope that I'll be able to find the magic incantations that make Apache do what I want it to do. In fact I looked tonight at the mono Web site and found that they have a whole section on configuring Apache. Tomorrow I'll try to put it into operation: but if it doesn't work I'll just have to make do with XSP.

In the meantime, if you want to look at how I'm getting on, you can visit:

http://linmono.uwic.ac.uk/MSc/Initial.aspx

You'll notice that the drop down lists now have data in them, and that any data you enter is validated before the application allows you to move to the next page. All that is done in the remote object.

You'll have to take my word for it that the application actually stores the data you enter ;)

More news tomorrow, hopefully.

A ray of light

by cc0028 @ 2006-02-23 - 20:16:38

Some progress was made today, hopefully.

I've been discussing my problems with the people on the mono mailing list all week. Early in the week, we managed to show that the problem was that the ASP.NET application could not access objects stored in the bin directory that is immediately below the application directory on the Web server. An application needs to do that for possibly two reasons:

  • To run code behind logic for pages where the source code files are not included in the application directory
  • To reference classes defined outside of the application code

I had already discovered that my application would not run unless the source code was included with it, but had not realised that the problem was that the application couldn't access the bin directory. What's more, at that point the source code did not make any external references; so it could be compiled on the fly and run without problem. The problem arises when a reference is made to the remote object proxy - an external reference.

Today, the ever-helpful Robert Jordan on the mono list suggested I try to run a small test application without source code, using a standalone XSP process instead of Apache. XSP is a minimal Web server for running ASP.NET code. It can be called as a standalone, or it can be used by Apache as a helper program.

When I did this, the code ran without problem using the binary DLL in the bin directory in the absence of source code.

So we have learnt that the problem lies in the way that I have Apache configured. Tomorrow, I'll try to learn a bit more about the problem and possible solutions. Over the weekend I'll try to implement the solution, getting the application to call the remote object. With luck, this won't be a problem if the application can access the precompiled binaries in the bin directory.

If the worst comes to the worst, but assuming I can call the remote object this way, I'll have to use a standalone XSP. In the event of a total disaster - not even XSP works - I'll try to use the Linux server as an application server only, calling it from the application running on a Windows box.

Wish me luck.

Subtitle bites back!

by cc0028 @ 2006-02-19 - 13:04:58

First the good news. I've finished coding the manual data entry part of my software and it all works just fine on my development box. The bad news is that I'm having difficulties deploying it to my Linux server.

Yesterday was a very long day spent in work trying to get it successfully deployed, but ultimately to no effect. There appear to be two problems. Firstly my remote business logic component does not appear to be listening as it should on the designated port on the Linux server. It works fine on my development (Windows) machine and can be called remotely from the Linux box by a test client that I've coded.

Secondly, my ASP.NET application, when running under Linux, does not appear to be able to create an instance of the remote object, even when it's looking for it on my development box where we know it works. We know that because the test client can call it from the Linux box. So why can't the ASP.NET pages?

I've posted to the mono mailing list, but not had any very helpful replies yet. This is probably not surprising because traffic is always less at the weekend. I'm monitoring the list, of course, but I think I'll post again on Monday if I haven't heard anything.

The highs and lows of postgraduate study. This must be the lowest.

Dyfal donc ...

by cc0028 @ 2006-02-11 - 20:12:54

... a dyr y garreg.

Repeated striking breaks the stone. Well that's our proverb for when we want to express the idea that progress comes in bite-sized chunks; or byte-sized I suppose I should say for the purposes of this blog.

Today I managed to get my remote object callable from a Windows service. I also created a new Web application to act as a gateway to the main program. This second application will be entirely invisible to users and will determine on a random basis whether a user will follow the Windows or the Linux route. Comparing the performance of the two is what this project is all about.

Lastly I added some code to the main Web application to call the remote object to fetch data, and to ensure that the pages of the application get called in order and that the data remains consistent no matter what the user may try to do. My hopes of getting it all done today were a bit wide of the mark, though, I'm afraid: but not to worry. I still have two weeks left on my timetable to get the application finished. About half of this consistency code - for want of a better word - is done; and the rest of it doesn't present any major technical challenges, I hope.

It all works on my development machine, which is a Windows box, but the big test will come when I try to deploy it to the Linux server. With luck, I should be able to give that a go during the week.

Fingers crossed.

Thief of time

by cc0028 @ 2006-02-08 - 21:54:34

No. Not procrastination. Me. I stole a couple of hours off my employer today to write a bit more of my application. Don't tell, will you.

I've mentioned before how this project is building an application that has layers: the presentation layer, the business logic layer and the data layer. The interesting bit, from a programming point of view is in getting the bits to talk to each other; in particular in getting the presentation layer to talk to the business logic layer.

In the old days of plain vanilla C programming, developers would have to set up a connection between the remote objects using something like the Berkley sockets library. Not only that; they would also have to create a protocol of some sort to enable the objects at either end of the communication to talk to each other. This may sound quite easy, but in fact it's very hard.

Computer programs these days don't just deal with simple scalar types like integer numbers or ASCII characters. Because every computer program is a model of the real world, in some sense, programs have to create and manipulate complex software artefacts that contain internal data (state) and behaviours (methods). Passing objects of these types over a serial cable between distant computers involves a process called, not surprisingly, serialisation - or, as the Americans will have it, serialization.

Manually creating your own protocol for serialisation, which is sometimes also called marshalling, is not a thing to be done lightly; so programming systems have developed ways of doing all this in the background so that the developer doesn't have to worry about it. This is something that, in my opinion, .NET is particularly good at.

But it's very detailed and exacting work. Over time, I've developed a way of working that helps me through the complexity. First I create the object that is going to be called remotely. In .NET this means creating an object that inherits from a class called MarshalByRefObject. I give this object all the state and methods (data and behaviour) that my model - the UML, remember - called for. I then build another object, called a local client, that will call the remote object locally for testing purposes. When I'm sure that this works as it should, I create what is known as a proxy object. This is what will be called on the remote client side. It interacts with the remoting infrastructure provided by the .NET Framework to provide marshalling and unmarshalling facilities that allow you to pass complex structures over the wire. Think of it like encryption and decryption, if you like.

When I have all that ready, I build a server that will listen on a port on the server for requests from the proxy. When it gets a request, it passes it on to the remote object, and the remote object carries out the requested task and returns whatever kind of object the client expects.

Then a remote client has to be built. It would be possible to use the client-side code in the application's presentation layer for this, but it's easier to build a little Windows Forms program (a GUI, if you like) that calls the remote object remotely and tests all its functions. Actually, it calls the proxy: but it thinks it's calling the remote object although it's the remoting infrastructure that does that in reality.

This is where I got to today. The journey was not without difficulties, but I can now call my remote object remotely and get back the answers I expect - data from the remote database, in this case. There's still quite a lot to do, though. The next step is to replace the console-based server I wrote today with a proper service that will run in the background even when no-one is logged on to the computer. Most people who have only dealt with personal computers find this a bit hard to understand, but there's not a lot to it, really. You just have to understand that it isn't necessary for anyone to log in to the machine for it to be fully functional. It just isn't accepting instructions from a human being - or at least not one who is logged in locally.

The final step will be to hook up the presentation logic in the code-behind pages of my ASP.NET application to the remote object, in response to the appropriate events. For example, the drop-down list box for countries needs to be populated with a list of countries from the database in response to the page load event of the demographic details page.

Hopefully I'll complete these steps on Saturday; unless I can steal some more time, of course.

A suitable case for treatment

by cc0028 @ 2006-02-08 - 14:07:08

I thought I'd found a problem with Mono. I wrote my program using .NET, on Windows, and deployed it to a Windows box where it worked perfectly happily. Put it on a Linux box and suddenly it could no longer connect to the database. Why?

These sorts of problems are very frustrating because you can't step through a debugger to find the problem. You have to try to imagine what's happening and work out logically where problems might occur.

OK. So I knew that the program had to read the database connection string from a configuration file. Maybe the file wasn't being read under Linux. Why would that be? Could it be that there was a difference in the way that .NET and Mono worked out their location on the file system?

Following a suggestion from the Mono mailing list, I changed the way the code worked out where it lived. Once again, everything worked fine on Windows, but not on Linux.

So next I by-passed the configuration file and hard-coded the connection string into the program. This is a very unprofessional way of doing things, but it is a good way of testing where the problem lies. After hard-coding, the program worked under both Windows and Linux, so for some reason, the configuration file was not being read properly under Linux. We'd eliminated the location problem so what could possibly be causing this behaviour?

Again, a suggestion from the mailing list caused me to do some checking.

The Windows operating system is case-insensitive. In other words, as far as Windows is concerned the file myConfigFile.config is the same as myconfigfile.config. This is not true under Linux - or under most sensible operating systems, to be honest. Under most systems, these would be two different files. So when my code told the program to look for its configuration information in a file called MScBusinessLogic.dll.config, but actually found only the file MscBusinessLogic.dll.config, Windows wasn't at all phased. Linux, on the other hand, looked for the file as instructed and simply didn't find it.

Changing the file name to agree with the instructions in the code simply made the problem disappear.

What a different an 'S' makes: especially when it's an 's'!

Hard labour

by cc0028 @ 2006-02-04 - 21:47:18

I spent another full day in work today, labouring on my thesis. I find if I go into work, I can get much more done. There are no distractions and I have all the facilities I need.

Today I'd hoped to complete the development of my remotely-called Business Logic and Data Access component. I suppose I ought to explain what I mean by remote components.

Not so many years ago, nearly all computer programs ran on the local machine on which they were installed. This is still true for a very large number of applications. For instance, most word processors, spreadsheets, games, graphics packages and so on just run locally: they don't talk to any other computers, and they don't need a network in order to be able to run.

However, there are a growing number of applications for which network connectivity is essential. Your Web browser is an obvious example of such a thing. In the business world, there are many other examples.

In the 1990s it became clear that standalone computers were not sufficient for many types of work. This was the era of the client/server model of computing where local computers ran powerful client applications that obtained their data from distant databases. Think of applications such as purchasing systems, payroll packages, personnel systems and many more. This is what is known as a two-tier architecture. With this pattern, the client application connects, most commonly, with a database server that could be located on a computer anywhere in the world. The server listens for client requests on a port. A port is not a physical entity by the way. Think of it more as an identifier, or part of an address. When a request is received the server fields it, carries out some processing such as retrieving a set of database records, and then returns an answer - the data, say - to the client.

All this is done over a network - certainly a Local Area Network (LAN), and possibly the internet.

By the end of the 1990s some problems were becoming apparent with the 2-tier model. Firstly, the proliferation of applications meant that many client applications had to be installed on many machines causing real maintenance headaches. Secondly, concerns about security meant that many companies were not happy with the idea of business rules being distributed around possibly hundreds or even thousands of client machines. A security breach on just one of them could mean that your super-secret method to beat the stock market slump became public knowledge; or perhaps a rogue employee could tamper with the program to make it misbehave in some way. To the rescue came the n-Tier architecture.

The n-Tier architecture is a pattern of software development that splits the system into at least three layers or tiers, for example:

  • Presentation
  • Business logic
  • Data

Each of these layers can run on a different computer, and might be located anywhere on the local LAN or the wider internet depending on the requirements of the user. The advantages of this type of development are that clients are much less powerful and easy to maintain, whilst sensitive information can be processed remotely on centralised servers, away from prying eyes and mischievous crackers.

There is no requirement for the layers to run on separate machines, by the way. The local machine is also a machine on the network and can be accessed as though it was a separate machine. You simply give the address of your local machine when you tell the program what machine you want to connect to for the different layers. By convention, the address of your local machine is always 127.0.0.1 or - more expressively for humans - localhost.

So what I am trying to do is to create a program that will run its presentation layer (the user interface) in a Web browser, its presentation logic layer on a Web server, its business logic and data access layer on a (virtual) application server and its data layer on a database server. In actual fact, the Web server and the application server are the same machine - but they don't have to be. Conceptually they are on two different machines. Lots of things in computing are conceptual and virtual.

Today I wanted to get the Business Logic and Data Access layer done. This is the layer that applies the business rules - e.g. determines whether a postcode or an email address is valid - and connects to the database. To do this, I've found that the most effective technique is to:

  • Develop the remote object (library)
  • Develop a local client that will call the remote object locally (without all that network stuff)
  • Develop the code for calling the remote object remotely

The reason for doing it this way is so that the functionality of the remote object can be tested using local method calls. Once this is done, you know that the logic in the remote object is correct. If problems then arise when the object is called remotely, you know that the problem is in the remoting code and not in the remote object logic.

Did I succeed? Well, not completely. I've got the remote object written and the local client for it: and it has been pretty thoroughly tested. The code for calling the remote object remotely has not been started yet, though. It looks as though that will have to be next week's objective.

It's a bit disappointing, but not the end of the world Not like Wales losing to England in the Rugby. I'm glad I was in work and didn't have to watch.

Familiarity breeds respect

by cc0028 @ 2006-02-01 - 14:37:10

The more I see of Mono, the more I admire the people who produce it.

In order for my project to succeed, I need to get three ducks in a row:

  • Ensure that .NET remoting works under Mono on Linux exactly as it does under .NET on Windows.
  • Get ASP.NET pages to run on Apache.
  • Succeed in accessing data in a remote MySQL database from both Windows and Linux, using the same code running on either .NET or Mono.

The first two I've already talked about at some length, so you know that I've managed to get both of those working. Today, the third item fell into place.

What is, to me, quite amazing is that I could sit down last night at home and write a simple program to access data in a database, then copy the resulting executable file onto my Linux server at work, run it, and have it working without any changes whatsoever.

OK, I know all you Java programmers out there are going to tell me that that's what you do all the time, but this is Microsoft, boys. They don't do interoperate.

Now all I have to do is to put all those items together, and I'll have a working system and not just a user interface. By the end of this week? Let's see if we can.


 
 

Footer

The content of this website belongs to a private person, blog.co.uk is not responsible for the content of this website.