Jurnal de călătorie

... despre ce se întîmplă cînd nu sunt acasă.
  Older »
 

littr.me

At one of my friends' suggestion I've started a new (week-end) project. So after about a couple days of work I can introduce: http://littr.me/. A beta version for sure, but I think it provides a good starting point for your basic scratchpad needs.

Yesterday I even had some sort of beta-testing by some friendly neighbourhood redditors. I only posted the link to the site to a small traffic subreddit just as a warm up, so the traffic amount wasn't too high. I am thinking about doing it again in a couple of weeks/days after I iron out a couple of others issues I'm not satisfied with.

During the test I detected no technical problems, and the suggestions they mentioned I have introduced. I'm glad one of them tried also to ... umm, crash the server with some really big requests, but apparently everything held together. The only down-side is that I forgot to enable the Google Analytics tracking, so I don't really have any page view stats. I guess I'll have to dig up the http server logs for some data.

Posted at 19:00 on Wed, 05 Oct 11

About : libVSC [3]

Another of the things I want to talk about, which I consider to be just good coding practice, but I seldom see it used in PHP development, is the usage of meaningful Exception handling. So I'll try to talk a bit about how Exception handling is used throughout libVSC.

Exception handling

Since PHP's own error handling is as useless as is simple, I decided to build a custom error handler to convert all problems generated by libVSC to custom Exceptions and handle them at various levels. You can see the code at set_error_handler() function and ErrorException objects. The code that does this, is quite simple and takes care of everything except Fatal Errors, of which I'll talk a bit about how I try to deal with them in order to fail as gracefully as possible. Here's some code:

function exceptions_error_handler ($iSeverity, $sMessage, $sFilename, $iLineNo) {
	if (error_reporting() == 0) {
		return;
	}

	if (error_reporting() & $iSeverity) {
		// the __autoload seems not to be working here
		include_once(realpath(VSC_LIB_PATH . 'exceptions/vscexceptionerror.class.php'));
		throw new vscExceptionError ($sMessage, 0, $iSeverity, $sFilename, $iLineNo);
	}
}

In this case vscExceptionError extends ErrorException, but mostly because I use a naming convention for Exceptions which assumes vscException is at the beginning of any exception. The purpose of this is to allow easy access from the IDE's auto complete. At the end of the exception's class name usually there is the module name. (Eg. vscExceptionController)

The above being said, I have hinted a bit the hierarchy I'm using for structuring the Exception related code. Namely modules (application, domain, presentation) and their sub-modules in turn, each have (well not exactly always) it's own set of Exceptions, to allow the control, as fine-grained as needed at catching time.

Next I'll give a couple of examples about handling them. First there's from the index.php file of a libVSC based application. This one is a bit useless, since if your Exception bubbled up to here, there's not really much you can do, except maybe display an error page to the user, or a debug stack to the developer.

// in the application's index.php file

try {
	import ('exceptions');
	import ('application/controllers');

	$oDispatcher = vsc::getDispatcher();
	$oRequest = vsc::getHttpRequest();

	// load the sitemap
	$oDispatcher->loadSiteMap (LOCAL_RES_PATH . 'map.php');

	/* @var $oProcessor vscProcessorA */
	// get the controller
	$oProcessor			= $oDispatcher->getProcessController ($oRequest);

	/* @var $oFrontController vscFrontControllerA */
	// get the front controller
	$oFrontController 		= $oDispatcher->getFrontController ();

	// get the response
	$oResponse 			= $oFrontController->getResponse ($oRequest, $oProcessor);

	// output the response
	$sContent = $oResponse->getOutput();
	ob_end_clean();

} catch (vscExceptionPackageImport $e) {
	// one of the two folders import()'ed couldn't be found in the include path
	if (vsc::isTesting()) {
		// show a stack trace
	} else {
		// show a 500 error page
	}
} catch (vscExceptionAutoload $e) {
	// one of the objects we tried to instantiate couldn't be found

	if (vsc::isTesting()) {
		// show a stack trace
	} else {
		// show a 500 error page
	}
} 

The next example is a better one, from the abstract front controller object. Which, as you can see above, generates a vscResponse object, based on vscProcessor and vscRequest. The front controller can handle Exceptions generated at the processor level and treat them accordingly. Mostly there will be problems with the model or the processor throes Redirect Exceptions (which is generated by the processor). For example a custom Controller can be created to also handle failed authentication attempts and redirect to a login page, or change the response type to an Access forbidden one.

try {
	$oProcessor->init();

	$oModel = $oProcessor->handleRequest($oRequest);
} catch (vscExceptionResponseRedirect $e) {
	// the processor wants to redirect 
	$oResponse->setStatus($e->getRedirectCode());
	$oResponse->setLocation ($e->getLocation());

	return $oResponse;
} catch (vscExceptionResponseError $e) {
	// we had error in the processor or model - trying to fallback gracefully
	$oModel = new vscEmptyModel();
	$oProcessor = new vscApplicationErrorProcessor(); // the error is application generated, output a 500 response

	$aStatusList = $oResponse->getStatusList();
	$oModel->setPageTitle($e->getErrorCode() . ' - ' . $aStatusList[$e->getErrorCode()]);
	$oModel->setPageContent($e->getMessage());

	$oMyMap->setMainTemplatePath(VSC_RES_PATH . 'templates');
	$oMyMap->setMainTemplate('main.php');
	if (!$oMyMap->getTemplate()) {
		$oMyMap->setTemplatePath (VSC_RES_PATH . 'templates');
		$oMyMap->setTemplate ('500.php');
	}
} catch (Exception $e) {
	// an unknown exception, bubble it up
	throw $e;
}
Posted at 01:06 on Fri, 23 Sep 11

About : libVSC [2.1]

In the light of the last article, I'll try to do a followup in which I'm going to talk about the folder structure of a web application based on libVSC.

The application folder structure.

htdocs/
   static/
      style.css
   index.php
lib/  
   application/
      processors/
         lformprocessor.class.php
   domain/
      models/
         userpassmodel.class.php
   presentation/
res/ 
   map.php
   login/
      config/
         map.php
      application/
         processors/
            loginprocessor.class.php
            logoutprocessor.class.php
            changepasswordprocessor.class.php
      domain/
         models/
            loginmodel.class.php
            changepasswordmodel.class.php
      templates/
         html5/
            logintpl.php
            logouttpl.php
            changepasswordtpl.php
         json/
            logintpl.php
            changepasswordtpl.php

As an example I'll use a very basic authentication module, and I'll describe a bit the different sections of the code.

Beside the two folders I have already stressed about in the previous post, at the top level we have the web server root, the htdocs folder. The default request processor of libVSC deals with URL rewritten paths, so we have only one point of entry, the index.php file. The static folder from here, is off course publicly accessible and can contain static resources.

Coming back to the lib/ and res/ folders, in the case of the application, they have slightly different uses. The libraries refer to generic objects used throughout the application and the resources can follow either the structure of libVSC (in the case of simpler applications) or have different modules as direct subfolders (as in my example) and then the aforementioned structure.

The map.php files contain the logic of URL mapping of our application. Here's an example:

// res/map.php
// mapping the http://app.local/login/ to the login module
$oMap = $this->map ('login/', LOCAL_RES_PATH . 'login/config/map.php');

// the res/login/map.php
// mapping url http://app.local/login/ to the login processor
$oMap = $this->map ('$' ,$sCurPath . 'application/processors/loginprocessor.class.php');
$oMap->setTemplate ('logintpl.php');

// mapping url http://app.local/login/logout/ to the logout processor
$oMap = $this->map ('logout/+$' ,$sCurPath . 'application/processors/logoutprocessor.class.php');
$oMap->setTemplate ('logouttpl.php');

// mapping url http://app.local/login/changepw/ to the change password processor
$oMap = $this->map ('changepw/+$' ,$sCurPath . 'application/processors/changepasswordprocessor.class.php');
$oMap->setTemplate ('changepasswordtpl.php');

// 404 controller - matching everything else to the standard 404 processor
$oMap = $this->map ('(.+)$', VSC_RES_PATH . 'application/processors/vscerrorprocessor.class.php');
$oMap->setTemplatePath(VSC_RES_PATH . 'templates');
$oMap->setTemplate ('404.php');

However the nice part of import() is that you can use whatever structure suits you and your project, libVSC not being dependent on a rigid naming scheme or folder structure. The only requirements are that classes are to be found in files having the .class.php suffix and the name lowercase of the class name.

Posted at 01:03 on Sun, 11 Sep 11

About : libVSC [2]

I think that good code structure should be one of the building blocks of any good project. In my opinion it should follow closely the logic your application is based on. Seeing that libVSC is trying to follow an MVC architecture pattern the underlying folder structure tries to have a similar separation between modules. So, I'll try to explain a bit the thought process that went behind it.

Code structure

Generally speaking there are two main sections of libVSC, the library and the resource folders. Extra (and somewhat ignored lately) there's a folder to hold the unit tests:

lib/
   application/
   domain/
   infrastructure/
   presentation/
res/
   application/
   domain/
   infrastructure/
   presentation/
unit_testing/

The lib/ folder contains abstract classes and interfaces.

The res/ folder contains specific implementations of the previous ones.

On the next level, the folders mainly share the same structure, which probably will be familiar to people having worked with similar web-development frameworks. There are however a couple of differences between them. Namely the library folder and all its subfolders also contain some exceptions related to the code in that specific module.

In the resources folder there is a subfolder containing basic output templates to be used by MVC views. On these I'll come back a bit later.

On the right hand side you can see a basic representation of the structure of the library and resources folders. In the next couple of paragraphs I'll be talking a bit about the purpose of each of them.

application

The application folder contains objects related to the Controller section of the MVC pattern. Unlike the standard MVC, in libVSC the Controllers have been split into two sections, one of them named Front Controller conceptually is more a part of a View as it deals with the types of output. The second one, named the Processor, is what can be considered a traditional controller, as it the section that feeds input into the logic layer of libVSC, the Model entity, and returns these models to the Front Controllers and Views to be displayed to the user.

The dispatcher and sitemap sections of the application module, contain objects related to the dispatching of view/request objects. Mainly they contain some logic processors for computing relations between GET requests to sections of your application. The actual logic of this mapping should be included in the sitemap files your application needs.

domain

This module consists of the Model related objects from MVC and provides uniform methods for accessing different types of data. It is separated in three submodules, which deal with the following parts of creating a data model.

Access contains objects which provide the means to interface with the persistent storage layer of your application, which can be a database, a flat text file, a json file, etc.

The domain submodule contains the actual entities that the model is based on top of. In the case of databases they abstract a table. In the case of a Json file, they contain the structure representation of a specific json object.

The model submodule contains the objects which actually interact with the other layers of the MVC. Namely they consist of business logic based on top of input received from the Processor and are used by the View to output the processed data.

infrastructure

This module contains objects which are not actually part of the MVC paradigm, but are used in one way or another by libVSC. As an example, most of the objects of libVSC are built on top of a basic vscObject which provides some fallback mechanisms in case of errors. On the vscNull and vscObject classes I'll come back at a later date.

presentation

The presentation layer has three main submodules. Two of them contain object wrappers for standard HTTP request and responses. The third one contains a simple View submodule, which is similarly built as Smarty just interprets standard PHP templates. Unlike Smarty, the templates are built with plain PHP as I don't think it's really necessary to invent a whole new language just for template output.

templates

In the resources folder, we have some basic templates used by libVSC. They are separated by mime-type and are used mainly for default responses, like 404.

application/
    controllers/
    dispatchers/
    processors/
    sitemaps/
domain/
    access/
    domain/
    models/
infrastructure/
    urls/
presentation/
    requests/
    responses/
    views/
templates/
    html5/
    json/
    rss/
    txt/
    xhtml
Posted at 22:23 on Fri, 09 Sep 11

About : libVSC [1]

As I was thinking about writing a short presentation about libVSC, I'll try to order my thoughts about it in a series of articles, just to provide a foundation for any future such work.

The import() function.

I shamelessly stole this one from Python, but I think I managed to provide a pretty good alternative to ugly code that results from deep include() statements. Here's a quick example from the Zend Framework:

/** @see Zend_View_Interface */
require_once 'Zend/View/Interface.php';

// ... snip
abstract class Zend_View_Abstract implements Zend_View_Interface { 

// ... snip

Granted, it's not so bad just looking at one file, but when you have a big project that uses the framework you'll need to include some more stuff. In the end, the beginning of your files would contain a big pile of include() statements, enough to discourage anyone from venturing further.

Coming back to the import() function. It's purpose is very similar, albeit in a smaller scope, with its Python counterpart. Basically it interprets the received parameter as a path and tries to create a new one iterating over the existing ones in the include paths array. When it finds a valid folder it adds it to the list. As an example:

/**
 * The include path would look something like this initially
 * "/home/habarnam/workspace/vsc-v2/lib/"
 */
import ('domain');

/**
 * After the call it would be
 * "/home/habarnam/workspace/vsc-v2/lib/"
 * "/home/habarnam/workspace/vsc-v2/lib/domain/"
 */
import ('access');

/**
 * After the call it would be
 * "/home/habarnam/workspace/vsc-v2/lib/"
 * "/home/habarnam/workspace/vsc-v2/lib/domain/"
 * "/home/habarnam/workspace/vsc-v2/lib/domain/access/"
 */

In my biased eye, it looks cleaner. Since this only adds folders to the include path, we need a simple __autoload() to actually load the file we need in the execution scope. A full example would look something like this:

// adds /home/habarnam/workspace/vsc-v2/lib/domain/models to the include paths
import ('domain/models');

// __autoload function finds the /home/habarnam/workspace/vsc-v2/lib/domain/models/vscmodela.class.php file and includes it
class vscEmptyModel extends vscModelA {

// ...snip

In the end there's no more need for long underscored names and long include paths as we have a simpler method for including the needed classes.

Of course, this method has its downsides. A first one is that this only works for entities capable of being included by an __autoload() call, namely classes and interfaces. If you need to include other types of files, you'll need to use the include/require mechanism. In my mind, this isn't actually a downside, but provides a cleaner separation between the logic of your application and other types of resources you might be needing.

Another problem is that makes the code a little harder to debug, since you don't know if your desired path has actually been loaded. Of course that when it fails it provides good feedback using the Exceptions handling mechanisms of libVSC (of which I need to write about at another time). Also I am planning to add to them the include paths data, so it provides a better debug method. On the other hand I don't really know how Python deals with this type of errors, so I might check that out too, to have a better understanding.

A final issue I see with it is performance. It is a piece of code that gets called a lot, the __autoload() part of it at least, and I need to be careful to not over extend the execution time needlessly. Also when the include paths list gets bigger might prove a bit challenging to import() new paths, but as of this moment I haven't really had problems.

These being said, you can check the code on my Gitorious repository and any feedback is welcome.

Posted at 01:34 on Sun, 04 Sep 11

About : spring


Mathilda awaiting assembly after the spring cleaning.

Posted at 20:22 on Fri, 18 Mar 11

There's work to be done...

I'm worried about getting too lazy. I need to start getting some things done. The order of things should be:

  1. Get Murphy back on linux. Still haven't decided which flavour to use. I would opt for my current one, Arch, but I was reading Daniel Robins' blog and Funtoo seems like an interesting option. However I'm still undecided if I'll appreciate compiling things again.
  2. Install my trusty IDE and get cracking to the remaining of my left projects.
  3. VSC where I need to finish the ORM layer. (PHP)
  4. The KIPI plugin for Imgur uploading. (C++/Qt4)
  5. Help porting systemd services to Archlinux. (C/Shell Scripting)

I have also promised some friends to help developing some sites for them. Hopefully finishing VSC should help here.

Posted at 19:45 on Mon, 30 Aug 10

Day 30: Arad


Whew... I made it, I now have been in Romania for the past two hours.
I just stopped to grab some food and write some final thoughts.

The last two days from Budapest were quite unpleasant because of having a quite strong head wind and temperatures of 35-40° Celsius. I'm glad my tires didn'd explode because of the heat. Other bad experiences were related to the huge amount of traffic on Hungarian national roads. The large number of trucks combined with the high temperatures have created across the lanes some waves in the asphalt, which destroyed the little shoulder space there was for the solitary bicycle riders like me. Riding there was a complete nightmare, and probably I'll wake up screaming when dreaming about huge TIR trucks sucking me in their draft over these dreaded asphalt waves. To be honest I'm glad that's over with.

But today it was a very good last ride. I managed a whooping average of 29 Km/h, which in comparison with the previous ones of maximum 22 I would consider as very impressive. The weather was perfect, warm enough but with plenty of clouds to shelter me from the sun. Also I had a nice tail wind most of the way, probably the biggest factor in the sudden increase of speed, which made up for the previous two shitty days.

As a side-note, you can have a very nice overall view of my travel by checking out the Picasa album location view.

These being said, I'll be on my way to find accommodation and have a long nice shower... judging by the stares people are throwing me around, I need it. Fuck them, for me it smells like I'm home.

Posted at 19:17 on Wed, 25 Aug 10

The only way home is riding home.

Today was pretty bad. It was also a Sunday.

The ticket ladies at Kelety destroyed my dreams of taking the bike on the train. It depressed me somewhat, as the possibility of ending my tour at any moment was one of the deciding factors in starting in the first place. I like having options. However, in order to get home I am left without anything except being on the back of a bike.

Lucian, mailed me some good news in this regard and this made me search on the CFR website for more information on bikes on the train. Apparently you can take your bike if it doesn't inconvenience the other passengers. My bike is large with all the stuff on it, so the decision to ride for a few more hundred kilometres still stands. Tomorrow I'll leave Budapest on my bike and this would have been the last stop that took more than a night.

To be honest I have no idea where I will end up. The initial plan is to make it to Romania, Arad or maybe even Timișoara. This would take three-four days (five at most) and will conclude this trip in a more honourable manner. However this isn't fun any more.

Even though, overall I think I'm in good physical condition, my legs feel quite heavy at the moment and this is after a good night's sleep and good protein/carbs full meals. My ankle is fine but in the last days my knees started hurting slightly after about 50-60Km. Let's hope this rest period helped.

My state of mind, however, is a different matter. I want to be home. I never liked Bucharest while I lived there, but the last two years spent in Brussels and the last three weeks spent on the road (which feel also more like years) made me really appreciate the significance of home, even though Bucharest is as far from this concept as either Brussels or Budapest. Home is where your TV is. I heard at one point. For me home is near my computer, Murphy. Home is near my friends, of which most of them I haven't seen in more than a year. I was planning to make the road my home, but I don't enjoy it any more, the last two days saw me blitzing through the Hungarian landscape, barely raising my eyes from the layer of asphalt that stopped being my friend.

A quote from a toilet that I used yesterday right after riding into Budapest seems to apply quite well to my case:

Slow down and enjoy life. It's not only the scenery you miss by going too fast – you also miss the sense of where you are going and why. — Eddie Cantor.
I never heard of this guy until now, but apparently he said some sage words in his time.

But don't you worry, I will make it home, be it in two days or two weeks. I will get there somehow and I will rest.

Posted at 23:37 on Sun, 22 Aug 10

Day 25: Budapest


At night Budapest is really the most beautiful city I've been to.

Finally I made it to what my legs felt to be the last stop. However, due to circumstances, it appears I will have to buckle up for a few hundred more kilometres.

My plan was to take the train to Bucharest and call it quits with just 900Km to go, after some painful 2000. Unfortunately, Saint Christopher – or Hermes – wasn't on my side on this one and none of the trains going to Bucharest are having any means to carry a bicycle on. So, here I am now, struggling between trying the Romanian way of doing things by bribing the conductor, or just man up and ride the rest of the way.

In order to clarify this situation, today I will have two main things to do: go to the Budapest-Kelenfold train station, there's a slight chance there's a train to Romania that can carry bicycles, or find a road map to plan the route to Arad. In the case of the later please wish me luck that my brakes or my legs don't fail me again.

To talk a bit about the road from Bratislava to Budapest, well it was again one of those roads that was longer than planned. I was under the impression that from Esztergom to Budapest there's less than 40Km and I was confident I can come dirrectly from Gyor. It wasn't the case, again the trail was winding so much along the Danube that the distances increased at least once and a half to the N11-N111.

Maybe I over did things but both nights I stopped, plus last night here in Budapest, I was extremely tired. My legs are in a constant state of discomfort and apparently the rest periods need to be more and more closer together and longer in order to be able to continue. This permanent state of tiredness is the main reason I want to stop. Of course, there's the boredom too. From here on end there won't be anything exciting to see, the route will mainly consist of national roads with lots of traffic and most of the times, bad asphalt.

Anyway this plays, please wish me luck, I'll need it.

Posted at 15:16 on Sun, 22 Aug 10
^top