Skip navigation.

exploreopera

| Help

Sign up | Help

Notes to self

Articles on development, software and the life that follows.

Eclipse crashes on 64-bit Linux

,

It seems that lots of people are experiencing their Eclipse IDE crashing more or less randomly on thei 64-bit Linux systems.

However, it seems that adding this:

-XX:CompileCommand=exclude,org/eclipse/core/internal/dtree/DataTreeNode,forwardDeltaWith


To your eclipse.ini fixes the issue, for some reason.

Bacon Ice Cream

Definitely a "Note to self" this one: Bacon Ice Cream.

I need to try that some day.

Fabric 0.0.4 Released

As promised yesterday, version 0.0.4 of Fabric has been released.

Here's a direct link to the news item:
https://savannah.nongnu.org/forum/forum.php?forum_id=5233

Fabric 0.0.4 this Weekend.

I was ill last weekend, plus we're preparing to push a new release of one of our major platforms at work, so I've overall been quit busy for the past three weeks.

This means that very little have been done on fabric, but don't worry; I haven't abandoned the project.

I'm also starting to recieve user feedback on fabric, so I'm happy to declare that I will push a 0.0.4 release this weekend based on that feedback!

Some of the changes will include no longer requireing a fabfile in the current directory to operate. This means that "fab list" and "fab help" will work even if you don't have a fabfile in your working directory. Also, doc-strings that start with a newline will no longer look empty when viewed with a "fab list"-ish command.

I hope you'll like that version.

After 0.0.4, I hope to have a major restructuring of fabric. In fact, I've already started working on this (in a git branch). The goal of the restructuring is to make it possible to extend fabrics runtime with plugins.

I really want to have the core of fabric stay small and simple, but I'de also like to help people who want direct support for various SCM systems and application servers. Plugins are the way to do this, I believe.

Other features I hope to support with the restructuring, will be built-in docs for variables, triggers (that fire when a variable changes or some operation/command gets run), a much better non-blocking IO subsystem for console output and finally a much improved terminal emulator.

But that won't all happen in one version, just so ou know :wink: Still, It's what I'de like to accomplish with fabric in the near-term future.

Fabric 0.0.2 Released.

, ,

Here's a sorry-for-previous-release-not-working-release; It's Fabric 0.0.2.

Hopefully it won't crash and burn as much...

Here's what's new:
  • lots of minor tweaks to the innards to make it a little less hacky (still plenty to do in that regard).
  • added a new download() operation; like put, but the other way around.
  • local() and local_per_host() operations now halt fabric if whatever they happen to be executing terminates with an exit_code != 0.
  • load() shoul now print a nicer message if no fabfile is found.
Appart from that, I've done work on a new and improved (!) shell command, but it's not ready for this version (maybe next). Also worked a little on unittesting this baby, but I haven't got much to show for that, either.

Real World Haskell's in public beta.

,

This means that the book site actually has some content now.. or, supposedly at least - I haven't seen it myself because the server is completely floored with load, but when it gets back on its feet, you can check it out here: http://book.realworldhaskell.org/.

The jQuery JavaScript Implementation Quality Metric

,

The jQJSIQM is, besides a horrible acronym, something that I've invented in the honor of the just recently released jQuery 1.2.2 library.

It is a metric for the quality of a JavaScript implementation, and works on three assumptions:
  • jQuery is a sizable and representative body of cross-browser JavaScript.
  • It is documented in the jQuery source, when ever something will trip up, or surprise a JavaScript developer - quirks of the particular implementation.
  • These quirks are bad, and therefor, the fewer the better.


In short: the fewer times a particular browsers name is mentioned in the jQuery source code, the better its JavaScript implementation is expected to be.

Bold claim? perhaps. Like all metrics, it should be taken with a grain of salt, and two grains of pepper.

Onwards! To the Numbers!

First contender is my favorite browser of them all: Opera. Let's see how it fares:
$ grep "Opera" jquery-1.2.2.js -c
7

Seven remarks. Well, eh. I suppose it could be worse. Let's keep an open mind for now, and remember that the upcoming version 9.5 has a completely revamped JavaScript engine that is rumored to be quite good.

Looking at market share, I'd say that Safari is probably Opera's closest contender. Safari also had its JavaScript engine revised in its version 3. Let's see if the boat floats.
$ grep "Safari" jquery-1.2.2.js -c
6

Woops! Looks like Safari is one-upping Opera on this test. Let's just hope that the Mac fanboys at work don't get hold of this data - I'd be havoc on my browser pride.

Scaling up on market share yet again, I think the Gekko browsers comes next. Mozilla and Firefox both have the same Spidermonkey JavaScript engine, so I'll consider them as one.
$ grep "Mozilla\|Firefox" jquery-1.2.2.js -c
8

Considering that Mozilla and namely Firefox has several truckloads more market share than Opera and Safari combined, I'd say that this result is quite encouraging.

Last on our list is the king of market share: Internet Explorer. It's been lambasted for almost a decade as the number one perpetrator in strangling innovation and holding the Internet back, but do these harsh claims stand a beatin'?
$ grep "IE" jquery-1.2.2.js -c
40

Woops. I suppose market share isn't the only area where IE is in the lead, it's pretty far ahead of the other browsers in quirk-count as well.

Since Opera, Safari and Mozilla/Firefox are so close to each other in this test, I don't think I'll declare a winner - if one of these browsers are your favorite, then feel free to think of it as a winner.

So now that we don't have any outstanding winners, it's time to ridicule the loser... by changing the "-c" to a "-n" in the grep command. Notice there's a couple of memory leaks mentioned in the output as well:
$ grep "IE" jquery-1.2.2.js -n|perl -p -e "s/\\s+/ /"
65: // Handle the case where IE and Opera return items
298: // IE copies events bound via attachEvent when
303: // attributes in IE that are actually only stored 
317: // removeData doesn't work here, IE removes it from the original as well
318: // this is primarily for IE but the data expando shouldn't be copied over in any browser
697: // IE has trouble directly removing the expando
823: // We need to handle opacity special in IE
924: // !context.createElement fails in IE with an error but returns typeof 'object'
968: // IE can't serialize <link> and <script> tags normally
981: // Remove IE's autoinserted <tbody> from table fragments
997: // IE completely kills leading whitespace when innerHTML is used
1047: // IE elem.getAttribute passes even for style
1051: // We can't allow the type property to be changed (since it causes problems in IE)
1055: // convert the value to a string (all browsers do this but IE) see #1070
1066: // IE actually uses filters for opacity
1069: // IE has trouble with opacity if it does not have layout
1120: // We have to loop this way because IE & Opera overwrite the length
1124: // (IE returns comment nodes in a '*' query)
1566: // to avoid selecting by the name attribute in IE
1580: // Handle IE7 being really dumb about <object>s
1808: // For whatever reason, IE has trouble passing the window object
1852: // event in IE.
1889: // Nullify elem to prevent memory leaks in IE
2015: // prevent IE from throwing an error for some hidden elements
2060: // Clean up added properties in IE to prevent memory leak
2080: // otherwise set the returnValue property of the original event to false (IE)
2087: // otherwise set the cancelBubble property of the original event to true (IE)
2293: // If IE is used and is not in a frame
2298: // If IE is used, use the trick by Diego Perini
2299: // http://javascript.nwbox.com/IEContentLoaded/
2365:// Prevent memory leaks in IE
2417: // to avoid any 'Permission Denied' errors in IE
2595: // IE likes to send both get and post data, prevent this
2637: // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
2795: // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
3307: // IE adds the HTML element's border, by default it is medium which is 2px
3308: // IE 6 and 7 quirks mode the border width is overwritable by the following css html { border: 0; }
3309: // IE 7 standards mode, the border is always 2px
3311: // However, in IE6 and 7 quirks mode the clientLeft and clientTop properties are not updated when overwriting it via CSS
3312: // Therefore this method will be off by 2px in IE while in quirksmode

Fabric 0.0.1 Released!

, ,

Last Sunday, after little more than two weeks of work, Fabric version 0.0.1 was been released. The main goal of this the very first release was to just get something out the door, and I must admit that some pretty horroble bugs made it through the cracks.

Fabric had most of its core functionality in place after just three days. Then came a period of polishing and bug squashing, and finally a lot of work on the help system and the distribution tool-chain these past four days.

I'll be celebrating this first release by transitioning Fabric from Pre-Alpha to Alpha. Also, I'de like to state my intend on release the cycles; that if anything at all has happened on Fabric since last release, then push a new version out the door every two weeks. The big idea is, that if I can just maintain this rythm, then the project is bound to move forward and not die out, regardless of how fast or slow the work progresses.

I'de like to make clear what version-numbering scheme I intend to use:
Before 1.0:
0.0.1 = First release
0.-.X = Backwards compatible update
0.X.0 = Backwards incompatible update

After 1.0:
-.-.X = Update without interface changes
-.X.0 = Update with backwards compatible interface additions
X.0.0 = Backwards incompatible update

And that's it for now. See you in two weeks, if not sooner.

Monads in Pythton

, ,

This is noteworthy: Peter Thatcher has implemented Monads in pure Python and gives examples of how to use them here: http://www.valuedlessons.com/2008/01/monads-in-python-with-nice-syntax.html

I don't quite get what's going in on in his code - needs more thorough reading, but it sure looks interresting.

ANN: Fabric - Simple pythonic remote deployment tool.

, , ,

Deployment woes.

I code in Java at work, and all of my projects can be divided into two camps:
  1. Those that build to .jar files and deploy to our maven2 repo.
  2. And those that build to .war files and are deployed to some application server.


Once configured, maven itself is pretty good at making case #1 run smoothly - "mvn deploy" is all it really takes. But do I have anything similar for case #2?

Well, not quite. I tried banging something together with Capistrano, but that didn't work. For one thing, Capistrano expects you to be deploying a Rails application and these are typically all deployed in the same way, which is very different from deploying a .war file. Secondly, I had a build/compile step in my process that I needed to do locally (because compiling on the server is troublesome and a bad idea), this meant that I had to use the put function to upload my .war file. Put worked nicely for small text files (ie. my project.properties file), but failed miserably when the payload war a near 20 MB heavy .war file.
Googling and tweaking the flags on the File object didn't work. It simply refused to upload that damn .war file.

Itch-scratchers mentality.

I suppose I could have written a shell script and leveraged the existing scp and ssh tool chain. And I did throw a pebble down this route to see how it felt, but eventually rejected the idea. The reason is that I'm deploying to multiple hosts simultaneously. I tried looking at clusterssh to see if it would help me in this regard, but it turned out to be odd, klonky and basicly not designed for such a task. I also took a look at Dancer's Shell, dsh, which was a lot closer to home, but my username contains a backslash and dsh meticulously stripped it out prior to logging in, foiling any and all of my attempts at tricking it into taking it at face value.

What was I suppose to do? I had pretty much given up on automating the process and started to accept defeat, when I happened upon the paramiko module for python. Paramiko is a pure python implementation of the SSH 2 protocol, and lets you log into servers, execute commands and upload files. It prompted me to the idea to write my own pythonic version of a Capistrano like tool, and then use that for deployment. It could be made open source and a perfect oppotunity try out Git on a real project.

Birth of Fabric.

So I swiftly went to work. In two days, I had written the first prototype. It supported the most basic operations such as running remote shell commands, sudo'ing and uploading files. Then I registered my project on nongnu.org (chosen because of their Git support). And ba-da-bim, Fabric became an open source project: https://savannah.nongnu.org/projects/fab/

Fabric looks, on the surface at least (or for those who've only spent a short while with either), a lot like Capistrano. You have a fabfile (as oppose to a capfile) in you project directory, and that file describes all of your deployment tasks (or commands, in Fabric speak).

Commands are really just regular python functions (and you're allowed to call it fabfile.py if you like) that simply makes calls to some other, more magical, functions called operations. Operations are magical because they just sort of exist; you don't import them from a module and don't find them in an object - you just call them.

So, to get the feet wet, here's a hello-world'ish simple fabfile:
set(
    fab_user = 'joe.shmoe',
    fab_mode = 'rolling', # run stuff on one host at a time
    fab_hosts = ['node1.servers.com', 'node2.servers.com'],
)

def deploy():
    "Build and deploy a war file to our app. servers."
    local("mvn clean package")
    put("target/myapp.war", "myapp.war")
    run("mkdir /rollback/$(fab_timestamp)")
    run("cp /$(fab_host)/deply/myapp.war /rollback/$(fab_timestamp)/myapp.war")
    sudo("cp myapp.war /$(fab_host)/deploy/myapp.war")
    sudo("$(fab_host) restart")


Then, all it takes to deploy is a "fab deploy" in the directory where the above file is found. It's still pretty basic, low-level and imparative, but it's a good start.

Fabric also has a built in help system that is powered by your doc-strings; try typing "fab help:deploy" for instance. If you want to see what other commands are availble to you, then simply type "fab list". You can also get a list of operations (the local(), put(), run(), sudo() kind of things) by typing "fab help:ops" and get more details about the individual operation with, for instance, "fab help:put".

And that's basically it for today.
July 2008
MTWTFSS
June 2008August 2008
123456
78910111213
14151617181920
21222324252627
28293031