20. Dezember 2009

Neue Wege im IT-Management: Artikel im VentureCapital Magazin 12/2009

Im aktuellen Heft vom VentureCapital Magazin ist mein Artikel über Scrum erschienen (Volltext hier und in der Printausgabe).

Keywords: IT-Management Agile Entwicklungsmethoden Investoren Internet-Startups Softwareentwicklung Pitch Projektsteuerung Scrum Cloud-Computing Open Source Kapitalgeber Time to Market Scrum eliminiert Unproduktivität "The Mythical Man-Month" Frederick Brooks wenige Funktionen Output mit Scrum verbessert Scrum-Prinzipien doppelte Geschwindigkeit Games- und Internetbereich Microsoft, Intel, Yahoo, Accenture, Adobe und GE Healthcare Enfant Terrible Mainstream Jeff Sutherland OpenView Venture Partners Venture Capitals Erfolgschance Investments Qualität Effizienz Due-Diligence Prüfung Impediments Hindernisse Heiner Wolf Gründer CTO virtuelle Welt weblin 3 Mio. User Chief Scientist Open Virtual World Projekt Social Games und Virtual Goods

26. November 2009

IT-Projekt der Bundeswehr in der Krise. Wie blöd kann man sein?

Die neue Nachricht: "beim IT-Projekt Herkules der Bundeswehr ufern die Kosten aus".

Eigentlich nicht ganz so neu. "Bereits im Juni hatte ein interner Bundeswehr-Bericht dem Projekt eine verheerende Bilanz ausgestellt".
Aber: Herkules kam in diesem Blog schon vor 5 Jahren vor: Grosse Softwareprojekte in der Krise.

Besonders interessante Fakten:

  • IBM, Siemens und der Bund haben für das Projekt ein Joint Venture gegründet
  • Seit 5 Jahren ist das Projekt in der Krise, aber Führungskräfte haben auch dieses Jahr Boni bekommen
  • Der Bund hat nichts zu sagen, da er nur 49 % der Anteile hält
  • Das Projekt "lässt sich inzwischen nicht einmal mehr kalkulieren"
  • Ministerium: Grund für steigenden Kosten ist fehlender Wettbewerb
Ist eigentlich schon jemand aufgefallen, dass der Bund 100% zahlt. Bei jedem Drecks-Startup setzen Investoren, die 30 % zahlen, jemand in den Aufsichtsrat. Ab 50 % Finanzierung haben sie gerne die Mehrheit im AR.

Der Auftraggeber hat den Dienstleistern gestattet, eine Abwicklungsfirma zu gründen. Wahrscheinlich hat jemand das dem Bund empfohlen, "um alles zu bündeln". Aber die wichtigste Eigenschaft dieser Firma ist, dass man sie einfach dicht machen kann, falls etwas schiefgeht. Der Bund kann dann nicht mal gegen den Auftragnehmer klagen. Der ist ja dann gelöscht. Siemens/IBM sind fein raus. Eine speziell gegründete GmbH ist DIE Methode, um Verantwortung abzustreifen. Das weiss doch jeder.

"Der fehlende Wettbewerb lässt die Kosten explodieren", hä? Was erwartet man denn, wenn man eine Firma mit der Abwicklung von mehreren Milliarden Euro beauftragt. Wo soll der Wettbewerb denn herkommen?

Wer hat eigentlich diesen Vertrag verhandelt? Das ist ja nicht nur Blödheit, sondern Untreue. Vielleicht sollte man sich mal anschauen wo das Management vorher gearbeitet hat. Ob da nicht jemand aus dem Ministerium rübergewechselt ist und jetzt gut verdient.

Wie wäre es mit einer parlementarischen Anfrage: Arbeitet jemand, der auf Seite des Bundes den Auftrag verhandelt hat, jetzt beim Joint Venture oder bei IBM/Siemens?

_happy_moneywashing()

21. November 2009

Integration Tests are a Superset of Unit Tests

The agile world is unit test crazy. That's ok. But it is not enough. Integration tests are a much under valued species. I like unit tests. I need unit tests. I do not know how we could ever build software without unit tests. But pure unit tests jump too short. We need more.

I am talking about unit test frameworks like NUnit. You just write the test function, add an attribute and the framework finds the function and adds it to the test list. Your test function tests a real function. Hundereds of those make a complete test set. Great, but not enough. What is missing?

You are supposed to write unit test code, which tests only single functions and methods. The idea is to isolate functionality and test isolated. I know the theory: Interfaces are contracts. There are unit tests for every behaviour. Even failures should be verified. TDD (test driven develpment) write the test as specification. I know all that bloat.

Fact is: these tests are important, but they ignore reality. Most problems result from interdependencies and side effects. In theory, there are no side effects. In reality they are there. Unit testing reduces them. Unit testing gives complex systems a chance to work. Chance is not enough. We must make sure, that systems work, not only functions. That's the part of the integration test.

Integration tests verify complex operations. Example: assumed I have a typical cached business object. An integration test would check the complete process:

  • fetch the object from the cache,
  • if it's not there, construct it from the DB,
  • put it in the cache and
  • return it at the same time.
  • communication with the DB includes a
  • web service interface and 2 layers of
  • storage driver and
  • SQL access code.
This is a vertical test.

In contrast: unit tests would test everything isolated:
  • does the cache access work? with a simulated in-memory cache. Beware of the network inside of unit tests.
  • does the database access work? using a fake DB, because relying on a real DB server is uncool, not "isolated" enough
  • would the webservice return the correct data? using a mock request object and fake data.
  • does the webservice format correctly? again: fake data
  • everything tested with made up configuration data and carefully constructed dependency injection.
I am totally pro isolated tests. But they are so un-real, mocked-up, simulated. They need something real on top. They need integration tests. Integration tests assert, that complex systems work despite complexity. We need integration tests. Wenn need lots of them. Unit tests just hope, that everything works together. Dream nicely.

We need integration tests anyway. And integration tests are in the real system. They are live. Unit tests are in a separate project and can not be live. Two separate test sets. Too many for me. There is no reason to split testing into 2 test sets, which are operated very differently. You run the test project from time to time and you are happy about the green bar. I run the real project all the time. Why should I run the test project from time to time, when I can run tests in the real environment with just one click.

Integration tests can be written to test isolated functions. They are a superset of unit tests. My interation tests check isolated functions PLUS vertical functionality PLUS live system health.

Unit test frameworks jump too short. They help, but ignore reality.
Get real. Switch to integration testing.

Update:

Changed the title from "Superior to" to "a Superset of".

_happy_testing()

3. November 2009

mod_mono Control Panel Extension

Just added a list of URLs to the mod_mono Control Panel (CP).

The Apache module mod_mono has a small control panel. The CP has some (actually very few) control features. You can see how many requests are currently processed, how many are waiting and you can restart the server process (the mono worker process, not the web server).

It can be enabled by

  1. <Location /mono>
  2. SetHandler mono-ctrl
  3. </Location>
Then go to http://your.host/mono. Unfortunately, it only shows how many requests are in work. I was missing information which requests are processed and waiting. I need the URLs. I want to know which ones take much time and which are blocking the server under high load.

So, I extended the CP to show a simple list of currently processed and waiting URLs.
  • First column is the request serial number.
  • The second colum is the processing time in seconds.
  • The third column is the URL with query.
Waiting requests are also listed. This happens only if the max processing limit is exceeded and requests wait (not in the screenshot). The waiting list shows the wait time instead of the processing time.

All data is stored in a shared memory segment.

BTW: mod_mono is programmed in C with not too much structure. No offense guys. I am very thankful for it. Great work. I know, it's open source. I should not complain, but improve it (which I did).

Why did I extend it? 2 reasons:
  1. I believe that an operator of a real service needs more information about what is going on than just the number of requests. We used apache server-status heavily. This is the same for mono.
  2. Flooding the server with dozens of integration tests, which spawn 200 backend requests each, stalled the server. I was afraid, that mon_mono has a problem under high load.
Once I knew the URLs, I could clearly see, that mod_mono is fine. It was just a normal deadlock situation where an frontend request tried to make a backend call via HTTP and could not get a free slot. Processing slots are limited by the thread pool. It can be increased, but there must be a hard limit. Allowing unlimited threads would make the server unusable under load, whereas deadlock situations can be avoided.

All slots are occupied by requests which wait for completion of backend requests, which do not find a free slot. Not a mod_mono issue. The situation has been resolved by splitting frontend and backend into separate mono applications. This is the normal configuration of a real multi-tier system, anyway.

The patch:

  1. % cd mod_mono-2.4.2/src
  2. % wget http://wolfspelz.de/download/mod_mono-2.4.2.patch
  3. % patch < mod_mono-2.4.2.patch
_happy_patching()

Update: the patch has been integrated into mono 2.6

29. Oktober 2009

How to Reactivate Weblin with 2 XML Files

In the forum of the Open Virtual World project someone posted a way to reactivate Weblin. Based on this information and after my own tests I can confirm, that it works.

It is even simpler and works without programming. All you need is a Web space to put some files.

You create a Jabber account on a public Jabber server, (e.g. http://register.jabber.org). Then put some files on your Web space and configure Weblin to use them. You need 2 XML files and an image as avatar. If you want an animated avatar then you need an additional XML and some animated GIFs.

Quick Try:

Enter in the Windows registry ...

[HKEY_CURRENT_USER\Software\zweitgeist\Firebat\2.0.0\Config\Operation]
PlatformLoginURL=http://ydentiti.org/test/Planta/login.xml
Restart Weblin .. and you are Planta. But, we do not want to be Planta, therefore to create your own...

HowTo:

The 2 most important files are login.xml and identity.xml. I have put both as examples on my web server:
http://ydentiti.org/test/Planta/login.xml
http://ydentiti.org/test/Planta/identity.xml
In login.xml is the URL of identity.xml and you have to enter the Jabber account: Jabber passwort ("secret"), Jabber user name ("planta") und Jabber server ("jabber.org").

In identity.xml is a link to the avatar image:
http://ydentiti.org/test/Planta/still.gif
Now you tell Weblin to use login.xml at startup. You set the registry key like this:
[HKEY_CURRENT_USER\Software\zweitgeist\Firebat\2.0.0\Config\Operation]
PlatformLoginURL=http://ydentiti.org/test/Planta/login.xml
Of course, that's the URL of your web space.

Where do you get the software from? Just copy the folder "C:\Program Files\weblin" from a friend. There is no installer required.

For Advanced Users:

Because the PlatformLoginURL is public, anyone can use this avatar (and the Jabber account). The Weblin login screen requests a password. It sends the password, but your web space probably returns the login.xml without checking the password. If you want to protect your login.xml, then you must create a login.php instead of the login.xml. Your login.php can check the HTTP Basic Authentication. You could also protect the login.xml with .htaccess. Attention: .htaccess protects the entire folder. Do not accidentally deny access to the other files. Anyone must be able to fetch your identity.xml and avatar image. You can put login.xml into a separate folder and set PlatformLoginURL accordingly.

For Advanced Users:

identity2.xml has an additional link to an animation file:
http://ydentiti.org/test/Planta/avatar.xml
which links to animated GIFs. This provides your weblin with actions and animations.

Required:
<config xmlns="http://schema.bluehands.de/character-config" version="1.0">
  <sequence group="idle" name="idle1" probability="1000" type="status" in="standard" out="standard">
    <animation src="still.gif" />
  </sequence>
  <sequence group="moveleft" name="moveleft1" probability="1000" type="basic" in="moveleft" out="moveleft">
    <animation dx="-100" src="left.gif" />
  </sequence>
  <sequence group="moveright" name="moveright1" probability="1000" type="basic" in="moveright" out="moveright">
    <animation dx="100" src="right.gif" />
  </sequence>
</config>
For the start copy this file and use your own GIFs. The XML and the GIFs are cached by the client. If you change something, you have to delete the client cache (C:\Documents and Settings\%USERNAME%\Application Data\zweitgeist\cache).

avatar.xml format in short:
  • <config> has multiple <sequence>
  • <sequence> has one <animation>
  • <sequence> has an attribut "group". This is the action, walk, stand, sleep, wave. If there are multiple actions in the same "group", then Weblin searches a <sequence> randomly controlled by the relative "probability".
  • <sequence> has an attribut "name". Must be unique, but can be anything.
  • <sequence> has an attribut "probability": relative frequency of the <sequence> in a "group"
  • <sequence> has an attribut "type" with values "status", "basic", "emote". "emote" appear as actions in the avatar-menu.
  • <sequence> attributes "in" and "out" can be ignored. They are for advanced uses with automatic selection of transitions between actions.
  • <animation> has only the attribut "src". An animated GIF URL absolute or relative the XML file

_happy_reviving()

23. Oktober 2009

Database as a Backend Web Service

The database is always the bottleneck. This is what all the admins of massive services tell in talks about their scaling efforts.

In short:

  • Database used to mean SQL
  • It is difficult to scale SQL CPU
  • It is simple to scale Web-Frontend CPU
  • The SQL philosophy puts the burden on Read by enabling very complex SELECTs and JOINs while Write is usually simple with short INSERT. Just the wrong concept in a massive world. We need quick and simple read operations, not complex reporting features.
Therefore many people step back from SQL and use other databases. Read more about the NoSQL movement. You have the choice: CouchDB, MongoDB, Tokyo Tyrant, Voldemort, Cassandra, Ringo, Scalaris, Kai, Dynomite, MemcacheDB, ThruDB, Cassandra, HBase, Hypertable, AWS SimpleDB, or just use Amazon S3 as stupid document store. Also SQL can be 'misused' as quick document/key-value oriented storage. It still has some key benefits.

Basically all you need is a key-value collection store with some indexing, alias document store. Whatever you decide: you are bound to it and this sucks. So, why not decouple the application logic from the database? Decoupling can be done in different ways. Traditionally you had a thin database code layer that tried to abstract from different (SQL) databases. Now, I need more abstraction, because there might well be a non-SQL database in the mix.

I decided to put a web service style frontend-backend separation between application code and database. This makes the DB a web service. In other words: There is HTTP between application and DB which allows for massive scaling. Eventually, my DBs can be scaled using web based load balancing tools. This is great. I can also swap out the DB on a per table basis for another database technology. Also great, because I do not have to decide about the database technology now and this is what this article really is about, right?

So, now I design the DB web service interface. I know what I need from the database interface. This are the requirements:
  1. Database items (think: rows) are Key-Value collections
  2. Sparse population: not all possible keys (think: column names) exist for all items
  3. One quick primary key to access the collection or a subset of key-values per item
  4. Results are max one item per request. I will emulate complex searches and multi-item results in the application (disputed by Ingo, see Update 1)
  5. Required operations: SET, GET, DELETE on single items
  6. Support auto-generated primary keys
  7. Only data access operations, no DB management.

This is the interface as code:

  1. interface IStorageDriver
  2. {
  3. // Arguments:
  4. // sType: Item type (think: table).
  5. // properties: The data. Everything is a string.
  6. // names: Column names.
  7. // condition: A simple query based on property matching inside the table. No joins. Think: tags or WHERE a=b AND c=d

  8. // Add an item and return an auto created ID
  9. string Add(string sType, Dictionary<string, string> properties);
  10. // returns Created ID

  11. // Set item properties, may create an item with a specified ID
  12. void Set(string sType, string sId, Dictionary<string, string> properties);

  13. // Fetch item properties by ID or condition, may return only selected properties
  14. Dictionary<string, string> Get(string sType, string sId, List<string> names);
  15. List<Dictionary<string, string>> Get(string sType, Dictionary<string, string> condition, List<string> names);
  16. // returns The data. Everything is a string

  17. // Delete an item by ID
  18. bool Delete(string sType, string sId);
  19. // returns True = I did it or False = I did not do it, because not exist, result is the same
  20. }

I added the "Add" method to support auto-generated primary keys. Basically, "Set" would be enough, but there are databases or DB schemes which generate IDs on insert, remember?

All this wrapped up into a SRPC interface. Could be SOAP, but I do not want the XML parsing hassle (not so much the overhead). WSDLs suck. Strong typing of web services is good, but can be replaced by integration tests under adult supervision.

On the network this looks like:

Request:
  1. POST /srpc HTTP/1.1
  2. Content-length: 106

  3. Method=Data.Add
  4. _Type=TestTable
  5. User=Planta
  6. Age=3
  7. Identity=http://ydentiti.org/test/Planta/identity.xml

Response:
  1. HTTP/1.1 200 OK
  2. Content-length: 19

  3. Status=1
  4. _Id=57646

Everything is a string. This is the dark side for SQL people. The application knows each type and asserts type safety with integration tests. On the network all bytes are created equal. They are strings anyway. The real storage drivers on the data web service side will convert to the database types. The application builds cached objects from data sets and maps data to internal types. There are no database types as data model in the application. Business objects are aggregates, not table mappings (LINQ is incredibly great, but not for data on a massive scale).

BUT: I could easily (and backward compatible) add type safety by adding type codes to the protocol, e.g. a subset of XQuery types or like here:

  1. User=Planta
  2. User/Type=text
  3. Age=3
  4. Age/Type=int32
  5. Identity=http://ydentiti.org/test/Planta/identity.xml
  6. Identity/Type=url

The additional HTTP is overhead. But SQL connection setup is bigger and the application is INSERT/UPDATE bound anyway, because memcache will be used massively. Remember the coding rule: the database never notices a browser reload.

Now, I can even use AWS S3, which is the easiest massively scalable stupid database, or Simple DB with my data web service on multiple load balanced EC2 instances. I don't have to change anything in the application. I just implement a simple 4-method storage driver in a single page. For the application it is only 1 line configuration to swap the DB technology.

I can proxy the request easily and do interesting stuff:
  • Partitioning. User IDs up to 1.000.000 go to http://zero.domain.tld. The next million goes to go to http://one.domain.tld.
  • Replication: All the data may be stored twice for long distance speed reasons. The US-cluster may resolve the web service host name differently than the EU cluster. Data is always fetched from the local data service. But changes are replicated to the other continent using the same protocol. No binary logs across continents.
  • Backup: I can duplicate changes as backup into another DB, even into another DB technology. I don't know yet how to backup SimpleDB. But if I need indexing and want to use SimpleDB, then I can put the same data into S3 for backup.
  • Eventual persistence:The data service can collect changes in memory and batch-insert them into the real database.
All done with Web technologies and one-pagers of code and the app won't notice.

Update 1:

Supporting result sets (multi-item) as 'Get' response might be worth the effort. I propose to have 2 different 'Get' operations. The first with the primary key and no condition. This will always return at most 1 item. A second 'Get' without pimary key but with condition might return multiple items. (Having both, a primary key and a condition in the 'Get' makes no sense anyway). The multi-item response will use the SRPC Array Response.

On the network:

Request:
  1. POST /srpc HTTP/1.1
  2. Content-length: ...

  3. Method=Data.Get
  4. _Type=TestTable
  5. _Condition=Age=3\nGender=male
  6. _Names=Nickname Identity

Comment: _Condition is a key-value list. This is encoded like an 'embedded' SRPC. A key=value\n format with \n escaping to get it on a single line. _Names is a value list. Tokens of a value lists are separated by a blank (0x20) and blanks inside tokens are escaped by a '\ '. Sounds complicated, but easy to parse and read.

Response:
  1. HTTP/1.1 200 OK
  2. Content-length: ...

  3. Status=1
  4. 0:Planta
  5. 0:Identity=http://ydentiti.org/test/Planta/identity.xml
  6. 1:Wolfspelz
  7. 1:Identity=http://wolfspelz.de/identity.xml

I am not yet decided about queries with multiple primary keys. They could be implemented as
  1. SRPC Batch with multiple queries in a single HTTP request, or
  2. with a specific multi-primary-key syntax, similar to SQL: "WHERE id IN (1,2,3)".
The response would be almost identical, because a SRPC Batch response is very much like SRPC Array Response. Solution 2 adds a bit of complexity to the interface with a new multi-key request field. Solution 1 does not need an interface extension, but puts the burden on the data webservice, which must re-create multi-key semantics from a batch of single-key queries for optimal database access.

Update 2:

I agree with Ingo, that solution 1 (SRPC Batch) makes all operations batchable and has a simple interface at the same time. The trade off, that the webservice must detect multi-key semantics from a batch is probably not too severe. Clients will usually batch ony similar requests together. For the beginning the webservice can just execute multiple database transactions. Later the webservice can improve performance with a bit of code that aggregates the batch into a single multi-key database request.


Update 3:

In order to allow for later addition of type safety and other yet unknown features, I define here, now and forever, that SRPC keys with "/" (forward slash) be treated as meta-data for the corresponding keys without "/". Specifically, that they should not be treated as database (column) names. That's no surprise from the SRPC point of view, but I just wanted to make that clear. I have no idea why someone would use "/" in key names anyway. I find even "_" and "-" disturbing. By the way: ":" (colon) is also forbidden in keys for the benefit of SRPC Batch. In other words: please use letters and numbers, the heck.



Update 4:

I removed the "Database". "Type" is enough for the data service to figure out where to look for the data. "Type" is a string. It can contain "Database/Table".



_happy_decoupling()

Google Toolbar Search History Menu is a Browser

I recently installed a Google toolbar to test Sidewiki. The toolbar replaces the search box by Google's own even if the toolbar is hidden.

Of course, Google has a better search box. It's popup menu has styled text and links. Probably cound even show videos. Guess what, the popup menu is an embedded browser.

The funny thing is, that weblin regards the popup menu as the frontmost browser window and the avatar jumps to the base of the window. As soon as the popup opens while typing, the avatars jump there.

It actually IS the front most browser window and weblin is right. Weblin also correctly calculates the base offset and moves the entire scene to the popup. Great stuff for insiders. Well done by those who worked on the brower positioning code over time.

_happy_popuping()

15. Oktober 2009

Aktuelle Metaprognosen zur Wirtschaftsentwicklung

Die Grafiken zeigen ab jetzt immer den aktuellen Stand:

Die Prognosen haben sich deutlich erholt. Das ging so schnell, dass sich die Diskussion um Krümmungsradien der ersten Artikel erübrigt hat. Es ist erstaunlich, wie sich die Prognosen an die Stimmung in der Wirtschaft anlehen. Eigentlich sollten sich die Prognosen aus Modellen ableiten und nicht nur aus Umfragen. Klar, Wirtschaft ist viel Psychologie, aber die Börse scheint in den letzten 18 Monaten besser die Zukunft zu prognostizieren, als die Wissenschaftler.

Während der Krise gingen die Prognosen leicht ins Minus, haben sich aber wieder erholt. Allerdings darf man diese Erholung nicht überbewerten, denn je tiefer der Fall in 2009, desto größer das Korrekturpotential in den Folgejahren. Ein 2 prozentiges Wachstum nach einem -5 % Fall hört sich nach solidem wiedererstarktem Wachstum an. Tatsächlich liegt die Wirtschaftsleistung aber noch 3 % geringer als 2 Jahre zuvor, während man in guten Zeiten eher +5 % für 2 Jahre erwartet. Also trotz scheinbar erholter guter 2 % eine Diskrepanz von 8 % zu einem guten Verlauf.

Februar 2009
April 2009
Juni 2009
Oktober 2009

_happy_trading()

9. Oktober 2009

Prior Art for the Eolas AJAX Patent

Eolas claims, that the U.S. Patent No. 7,599,985 covers AJAX and other mechanisms, which execute in the client and communicate with the server to update parts of the page.

The patent was filed August 9, 2002. How can the patent cover AJAX ? AJAX was invented by Microsoft and published in Internet Explorer 5 in March 1999. The next version, IE 6 in August 27, 2001 had the updated (final) version of the XmlHttpRequest object. IE6 also had a fully developed DOM model. Microsoft used these features for interactive Web applications like Outlook Web Access. Actually, some say the XmlHttpRequest object and the "technology" has been specifically developed for Outlook Web Access (OWA). OWA was available in Exchange 2000.

So, there was at least a product with documentation available. Even if the product handbook does not disclose the "technology", there are for sure developer documents, which explain XmlHttpRequest.

I know there were, because we used XmlHttpRequest in a project in 2002 before the patent was filed, before XmlHttpRequest became known as AJAX and before AJAX lost it's X(ML) and became AJAJ (Asynchronous HTTP and JSON).

Screenshot of the project, where a bluehands project for a german energy company violated the Eolas patent before it was even filed.

_happy_violating()

7. Oktober 2009

6. Oktober 2009

Scripting Configuration for C#

Configuration is a scripting task.

Since I am fed up with the bracket mess of mono/.NET web apps, I was thinking about a more convenient configuration system. Most configuration systems lack flexibility, because they just evaluate a static file and set some values. Some allow for includes, but not much more. But advanced applications need more flexibility, in other words: code. If the config file is a script and has access to the application, then you have all the flexibility you need, and type safety.

And what is the most natural config script language for a C# project? C#, of course.

All you need is a script engine like CS-Script. Add the script engine, create a script host, load the config script file on application start and execute it. The best part is, that the configuration file is type safe and can be edited by the usual development system.

Here are my code bits:

Add the CSScriptLibrary.dll to the project References.

Create a class that implements the script file loader: ScriptedConfig.cs

using System;

namespace MyApp
{
public class ScriptedConfig : MarshalByRefObject
{
public string BasePath { get; set; }

public void Include(string sFile)
{
using (CSScriptLibrary.AsmHelper helper =
new CSScriptLibrary.AsmHelper(CSScriptLibrary.CSScript.Load(
BasePath + sFile, null, true)))
{
helper.Invoke("*.Configure", this);
}
}
}
}
A class that implements my specific configuration object derived from ScriptedConfig: MyConfig.cs:
using System;
using System.Collections.Generic; // just for the sample Dictionary

namespace MyApp
{
public class MyConfig : ScriptedConfig
{
// Just some sample values
public string sText1_ = "empty1";
public string sText2_ = "empty2";

// A sample dictionary to hold more values
public Dictionary<string, string> values_ = new Dictionary<string, string>();
public Dictionary<string, string> Values { get { return values_; } }

public string Text2 { get { return sText2_; } }
}
}
The application startup code:

MyConfig myconfig = new MyConfig ();
myconfig.BasePath = AppDomain.CurrentDomain.BaseDirectory; // For my web app
myconfig.Include("ConfigGlobal.cs");
I have a global config file, that is the same for all installations and a local config file that overrides the global setting for the test syste, the stage system or the production system. This is the ConfigGlobal.cs:
using System;
using MyApp;

public class Script
{
public static void Configure(MyConfig c)
{
c.sText1_ = "Global Config 1";
c.sText2_ = "Global Config 2";

c.Include("ConfigLocal.cs");
}
}
The global config file invokes the local config file, which configures the same object. ConfigLocal.cs:
using System;
using MyApp;

public class Script
{
public static void Configure(MyConfig c)
{
c.sText2_ = "Local Config 2";
c.values_["Text3"] = "Local Config 3";
}
}
You access the config values like:

string t1 = myconfig.sText1_;
string t2 = myconfig.Text2;
Actually, in my current project I separate my code from the implementation of MyConfig by a facade pattern using an interface (IConfig) and in addition access the config instance via StructureMap and a global static wrapper (Config).

It rather looks like:

string t1 = Config.Get("Text1", "Default1");
string t3 = Config.Instance().Values["Text3"];
But that's for later.

_happy_configuring()

2. Oktober 2009

Copying Large Files on Windows

Copying large (>50 GB) files seems to be a problem on Windows (XP). Windows Explorer fails after some time with "Insufficient system resources exist to complete the requested service. (error 1450)". I use GoodSync as a folder syncing program. It has the same problem. I even have a commercial license, because I use it for software deployment on WebDAV and other remote file systems. Suprisingly this commercial file copy program also fails after about 50 GB.

GoodSync support told me "i am not sure why you expect that windows can handle 85 gb file". Good joke. This is the 21st century, guys. Why should it not? Apparently, GoodSync uses the Windows function CopyFileEx. Probably the same as Windows Explorer. I don't know what's wrong with CopyFileEx. There is an old MSDN knowledge base article (kb259837), which admits a problem and continues, that it has been fixed in Windows 2000 SP2. Since Win XP is just an updated Win 2k (XP major version 5.1 compared to 5.0, Vista is 6.0), I suppose the problem is also fixed in XP.

I wrote a simple copy program using the POSIX API (fread/fwrite) which uses Win32 ReadFile under the hood instead of CopyFileEx. Just works. It does as many MB/sec as physically possible, and uses only 1.6 MB memory. So, what's the problem?

Considered my half page of code, CopyFileEx really sucks. The funny part is, that while copying large files in Windows Explorer makes the PC unresponsive and is no fun, my small program copies peacefully in the background. I am so good. Or is CopyFileEx just so bad? Probably the latter. There is nothing special with my code. No fancy tricks, just the basic 1st year CS bachelor stuff.

Lets call it "scopy" for simple copy because all things I do are not stupid, but simple:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
if (argc != 3) { printf("Usage: %s src dst\n", argv[0]); return 1; }

char const *szSrc = argv[1];
char const *szDst = argv[2];

FILE* fSrc = fopen(szSrc, "rb");
if (fSrc == 0) { printf("Error opening %s\n", szSrc); return 1; }

FILE* fDst = fopen(szDst, "wb");
if (fDst == 0) { printf("Error opening %s\n", szDst); return 1; }

size_t nSize = 1024*1024;
unsigned char* pBuf = new unsigned char[nSize];
if (pBuf == 0) { printf("Error allocating %d bytes\n", nSize); return 1; }

int nCnt = 0;
__int64 nTotal = 0;

bool bDone = false;
while (!bDone) {
size_t nRead = fread(pBuf, 1, nSize, fSrc);
if (ferror(fSrc)) {
perror("Read error"); return 1;
} else {
size_t nWritten = fwrite(pBuf, 1, nRead, fDst);
if (ferror(fDst)) {
perror("Write error"); return 1;
}

nCnt++;
nTotal += nWritten;

if (feof(fSrc)) {
bDone = true;
printf("\n%I64d\n", nTotal);
} else {
printf("%d ", nCnt);
}
}
}

delete[] pBuf;
pBuf = 0;

fclose(fSrc);
fclose(fDst);

//char c = getchar();

return 0;
}

_happy_copying()

1. Oktober 2009

Weblin wiederbeleben mit 2 XML Dateien

Im Forum des Open Virtual World Projekts hat jemand einen Weg gepostet mit dem man Weblin wieder betreiben kann obwohl die Server abgeschaltet worden sind. Basierend auf diesen Informationen und nach meinen eigenen Tests kann ich bestätigen, dass es geht.

Es ist sogar noch einfacher und ohne Programmierkenntnisse.

Man muss nur auf einem öffentlichen Jabber Server einen Jabber Account anlegen (z.B. http://register.jabber.org). Dann auf einem Web-Space ein paar Dateien hinlegen und Weblin konfigurieren, dass es diese Dateien benutzt. Man braucht 2 XML Dateien. Dann natürlich ein Bild als Avatar und je nachdem, ob man ein animiertes Avatar will, noch ein XML mit GIF Animationen.

Schnell mal ausprobieren:

In Registry eintragen...

[HKEY_CURRENT_USER\Software\zweitgeist\Firebat\2.0.0\Config\Operation]
PlatformLoginURL=http://www.ydentiti.org/test/Planta/login.xml
Weblin neu starten ... und du bist Planta. Aber wir wollen ja nicht jeder Planta sein, deshalb...

So geht es:

Die 2 wichtigsten Dateien sind login.xml und identity.xml. Als Beispiele habe ich diese 2 Dateien gemacht und auf meinen eigenen Webserver gelegt:
http://www.ydentiti.org/test/Planta/login.xml
http://www.ydentiti.org/test/Planta/identity.xml
In login.xml steht der URL von identity.xml und man muss den JabberAccount, also Jabber Passwort ("secret"), Jabber Username ("planta") und Jabber Server ("jabber.org") eintragen.

In identity.xml ist ein Link auf das Avatarbild:
http://ydentiti.org/test/Planta/still.gif
Jetzt muss man nur noch Weblin beibringen, dass es das login.xml benutzt beim Starten. Dazu einen Registry Key setzen. Beispiel:
[HKEY_CURRENT_USER\Software\zweitgeist\Firebat\2.0.0\Config\Operation]
PlatformLoginURL=http://www.ydentiti.org/test/Planta/login.xml
Natürlich muss hier der richtige URL von deinem Web-Space stehen. Vielleicht programmiert Marmel ja ein Tool dafür :-)

Ach ja, wo bekommt man die Software her? Einfach von eine(r|m) Freund(in|) den Ordner C:\Programme\weblin kopieren. Kein Installer nötig.

Für Fortgeschrittene:

Da der PlatformLoginURL öffentlich ist, kann jeder dieses Avatar (und den Jabber Account) benutzen. Weblin fragt beim Start zwar ein Passwort. Das wird aber nicht verwendet, da bei PlatformLoginURL ein statischer URL eingetragen ist und nicht eine echte Web-Applikation, die das Passwort prüfen würde. Wenn man nicht will, dass andere das gleiche Avatar verwenden, muss man wie in dem Forum Post vorgehen und statt login.xml ein login.php programmieren, dass HTTP Basic Authentication prüft. Alternativ kann man auch das login.xml durch .htaccess schützen. Vorsicht: dabei nicht Zugriff auf die anderen Dateien verbieten. Man kann das login.xml dafür in ein anderes Verzeichnis legen und den PlatformLoginURL entsprechend setzen.

Für Fortgeschrittene:

Man kann den PlatformLoginURL auch in Firebat.sreg eintragen, wenn man mit leerer Registry startet. Registry überschreibt Einstellungen in Firebat.sreg.

Für Fortgeschrittene:

In identity2.xml ist auch ein Link auf eine Animationsdatei:
http://ydentiti.org/test/Planta/avatar.xml
die auf die GIFs mit den Animationen verweist. Dann hat der Weblin auch Aktionen und bewegt sich.

Notwendig ist mindestens:
<config xmlns="http://schema.bluehands.de/character-config" version="1.0">
<sequence group="idle" name="idle1" probability="1000" type="status" in="standard" out="standard">
<animation src="still.gif" />
</sequence>
<sequence group="moveleft" name="moveleft1" probability="1000" type="basic" in="moveleft" out="moveleft">
<animation dx="-100" src="left.gif" />
</sequence>
<sequence group="moveright" name="moveright1" probability="1000" type="basic" in="moveright" out="moveright">
<animation dx="100" src="right.gif" />
</sequence>
</config>
Zum Start am Besten dieses kopieren und nur eigene GIFs verwenden. Das XML und die GIFs werden im Client gecached. Wenn man was ändert und die Änderung sehen will, dann Client Cache löschen (C:\Dokumente und Einstellungen\%USERNAME%\Anwendungsdaten\zweitgeist\cache).

Format in Kürze:
  • <config> hat mehrere <sequence>
  • <sequence> hat ein <animation>
  • <sequence> hat Attribut "group". Das ist die Aktion, laufen, stehen, schlafen, winken. Es kann mehrer mit gleicher "group" geben, dann sucht Weblin eine der <sequence>s zufällig aus gesteuert durch die relative Häufigkeit ("probability").
  • <sequence> hat Attribut "name". Muss nur eindeutig sei, aber beliebig.
  • <sequence> hat Attribut "probability": Relative Häufigkeit der <sequence> innerhalb einer "group"
  • <sequence> hat Attribut "type" mit Werten "status", "basic", "emote". "emote" tauchen als Aktionen im Avatar-Menu auf.
  • <sequence> Attribute "in", "out" kann man mal ignorieren
  • <animation> hat nur das Attribut "src". GIF URL absolut oder relative zu der XML Datei (mit oder ohne http://...)

_happy_reviving()

PS:
Liebe Dunkle Seite der Macht: Das sind alles öffentliche Informationen, bzw welche, die schon vor 2006 bekannt waren. Keine Chance Ärger zu machen. Weblin ist einfach so gut programmiert, dass sowas geht. Vielen Dank auch an das Programmierteam, dass es trotz neuem Accountwizard so geblieben ist.

25. September 2009

Google Sidewiki

Google launched its new Sidewiki feature. Sidewiki opens an annotation sidebar on every Web page. Sidewiki is a Google Toolbar feature. You can leave notes (annotations) on every Web page and see notes of other people. The annotations appear is a sidebar. This is not the browser sidebar, but an extension driven page element. The feature looks quite advanced. It has rating system integrated, crowd driven spam identification, you can choose to see only annotations in your language. While posting an annotation you can send the same text also to your blogs.

Sidewiki is not real virtual presence, as you do not see the people who are on the page at the same time. Sidewiki is also not a new concept. Annotations have been here before, as early as 1999. But Sidewiki is important for virtual presence, because it shows, that a major player is moving closer. A big advantage of annotations compared to virtual presence is that annotations persist. Chats on a Web page are transient. They are gone after you leave. Annotations stay (for some time). You can leave your mark in the world. That's what people want. They want to create something that persists.

Important for virtual presence is, that Google invests in the notion, that Web pages are places. They are not just an anchor for places, like in Lively. The plain Web page identified by it's URL is a place where things happen.

_happy_wikking()

The usual weblin annotation: when a "great manager" told investors, that virtual goods would not work as a business model, he proposed "annotations". What a disaster would that have been to get Google as a direct competitor. Oh right, the decision was correct, because nobody could have known. I heared that before. Being right because of not knowing seems to be a constant.

24. September 2009

TwiX - Jabber Twitter Gateway Version 0.4.8

I was spamming my twitter account accidentally. Actually it was my Jabber/Twitter gateway, which got an XMPP error message from a broken jabber server and tweeted the error, then sent me a confirmation, got another error message and tweeted it again. Infinite loop!

The main problem is, that the error message looks very much like a good message. That's a Jabber "feature". A good message looks like:

<message from="JID" to="JID">
<body>...Started</body>
</message>
If that produces an error, then comes back:
<message from="JID">to="JID"type="error">
<body>...Started</body>
  <error code="500" type="wait">
  <internal-server-error xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" />
  </error>
</message>
...which looks very much like the original message, if you do not check for the type="error" bit and just forward the body to the twitter API.

Fixed.

TwiX has now been updated to version 0.4.8. Get it here.

_happy_looping()

16. September 2009

ejabberd crash solved by raising number of network connections

I was bothered by ejabberd crashes. Suddenly it started to crash quicky. The crash dumps said something like:

eheap_alloc: Cannot allocate 747325720 bytes of memory (of type "heap")
and:
eheap_alloc: Cannot allocate 934157120 bytes of memory (of type "old_heap").
I tried the installer, tried compiling erlang and ejabberd from source. I usually run ejabber in a virtual server. I tried on the native host. Nothing helped. We had a similar problem before with a memory bug related to mnesia tables where a server with 5000 clients reaches 3 GB in 5 days and crashes. That case was solved by upgrading the erlang runtime from R12B-3 to R12B-5.

But in this case it needed only 5 minutes and 1000 users to suck up the entire system memory. This was different. The number of about 1000 client connections was the constant of all crashes. @zeank suspected that the problem is the limit of open file descriptors, 1024 by default. The open file descriptor limit means also the max number of TCP (client) connections. Setting this to a higer value, e.g. 32.000 solves the problem.

In practice: insert into ejabberdctl
after:
ERL_MAX_PORTS=32000
the line:
ulimit -n $ERL_MAX_PORTS
_happy_ejabbering()

2. September 2009

Twitter Microtagging = Personal Tags

It is time for structure in Twitter. I will now start microtagging my tweets so that followers can filter and read only what they are interested in.

Hashtags are currently used for several purposes:

  1. Global tagging: is done in the spirit of tag-clouds to support global search for topics. example: "Official hashtag for Barcamp Bangkok 3 is #barcampbkk3".
  2. Comment tagging: is a very recent development. People started to add single word comments which support or augment the original tweet in form of hashtags. Example: "Got my iPhone today #happy". Nobody would search for #happy. Its just a funny (and completely valid) mis-use of tagging.
  3. Data tagging: to use Twitter as a data channel for later evaluation. Example: "My current #weight 72.2 kg" with the convention that after #weight follow a number and a unit. Example: "I am now at Los Angeles Airport #geoloc 33.94 -118.40" with the convention that after #geoloc follow longitude and latitude. Rarely used though and probably yet underrated.
  4. Follower phishing: is done by adding as many hashtags as possible to the tweet in the hope to attract attention of followers, specifically auto-followers which are triggered by certain keywords. Example: I once was followed within seconds by @timmendorf when I twittered #helgoland (both are beach holiday resorts).
Hashtags are the community driven Twitter way to give a litte bit of structure. But this is not enough. What we need is a way to filter relevant information from streams. I am tweeting different parts of my life. I tweet about my work, about various projects, about my lunch, about the kids, about fun stuff I find. But, there are followers who are not interested in my kids. My familiy is not interested in technical tweets. Parts of it is always spam for some of my followers. They have no way to filter only the interesting tweets. There should be a way for me to tag my tweets with my own personal tags, so that followers or their client software can select what they read. This is Microtagging: short personal tags.

I will now start to add short tags to my tweets which indicate a kind of "sub-channel" inside my tweet stream. You (or your software) will be able to ignore #dev tweets if you are not interested in my development work. You may ignore #kids tweets if you do not want to know when we are having ice cream in the local zoo. Microtags are personal tags. Everyone can define her own. They are not globally defined. Microtags have only meaning inside a single Twitter account. There might be standards later. Until then read my microtags at microtags.org to learn what they mean.

I will start with:
#life What I do, eat, where I walk and other spam
#me About me, but not the trivial #life stuff
#chat Chats via twitter, which you'd probably ignore if your r not @'d
#fun Fun stuff I find and want to share
#pol Politics (I am trying to avoid this)
#fam Family matters and events
#me About me, but not the mundane #life stuff
#blog New blog posts announced on twitter
#web The Web, Internet including social media, social networks and Twitter
#vw About virtual worlds
#soc Society, including rants about how bad/good the world is
#sci Science, if any
#kids Not yet
#dev Software development and tools
#tec Technical stuff except software development
#ovw That's the project I am currently working on most of the time
#vg My series of Virtual Goods Articles (see http://blog.wolfspelz.de/2009/10/virtual-goods-ticker.html)

A twitter client could have multiple input fields, so that I do not have to choose the microtag for each tweet. A twitter client could automatically fetch the microtags of a new follower from microtags.org and show you a list to select from. My list is at http://microtags.org/tags/?http://twitter.com/wolfspelz. Your twitter client could also fetch my microtags from time to time and offer new choices if they change.

I'd rather make these tags metadata for the tweet and not as part of the text. But since there is not metadata in microblogging, there will now be microtags in the text. Clients can strip them anyway.

_happy_microtagging()

See also: http://www.microsyntax.org but I can't wait anymore.

17. August 2009

HTML Video Tag

They did it again. 15 years after the img-tag, they invented a video-tag. I know, that native video makes the world better. I am totally pro-video. But to call the tag "video" is just plain wrong.

In HTTP, the server tells the content type of data. The client has no say. But if you call a tag "img" (or "video") then the browser expects a certain (subset) of content types. Ever tried to return an HTML from the URL of an img-tag: broken image. Even though it was valid HTML. Why doesn't the browser show an embedded HTML fragment instead? Why does it insist on an image? The browser requests a resource by URL to fill some screen space. If the server returns HTML, the client could show the HTML. This would have eliminated the need for frame and iframe.

One embed-tag would have been enough instead of img, iframe, and video. An embed-tag would simply tell: "here comes some screen space that is to be filled with the src-URL". And nobody would care if the content type is an image or PDF or video or HTML.

On the other hand, it's not really that bad.
Not really worth a rant.
Thanks for the native video, guys.
It's cool.
Especially combined with (the much too long ignored) SVG.

:-) It's not like embedded native video hasn't been postulated 13 years ago. I asked them at RTMW 96 (last century), if they would just add a video codec to the browser and a simple request/response. But back then, people wanted to make it complicated with RTSP, multimedia frameworks and such. In the meantime we had never-really-working-MPEG-plugins, a Microsoft video player disaster, a Flash workaround, because Macromedia just could not stand it anymore. Finally, the browser guys made it as simple as requested in 1996.

_happy_embedding()

9. August 2009

The Fake Transition

Weblin does NOT transition to club cooee. Rather, club cooee uses the email addresses to advertise its own product. While both are avatar services, weblin is a layered virtual world on the web and cooee is not. We all know that there are many different avatar services. Cooee is NOT a functional replacement for weblin. RocketOn is the only system that could be called a similar service. Cooee is just another avatar system that desparately needs registered users. The general terms of weblin explicitly forbid the use of user data for this purpose.

But the management of cooee, the weblin liquidator Jörn Weitzmann, and the ex-CEO Jan Andresen conspired against the weblin founders to shut down weblin, primarily to make this fake "transition" press release possible. The founders tried to keep the service alive and the user data safe. We put up the general terms in the way we did to prevent this. We notified the liquidator several times. We are very sad, that the email addresses are used unlawfully for advertisements. This is an expression of a mind set that does not respect the written law, but only court orders. In other words: they hope to get away with it, because nobody sues. And even if someone sues, then they can handle a minor fine for a major press release.

Cooee and Jan Andresen outbid the founders in a blind bidding process by a very narrow margin, that raises suspicions on its own. Weblin could have survived. The founders offered to pay for operating and maintenance cost. It is now being terminated in order to shuffle users to cooee. The intention of cooee is understandable, only the means are unlawful. But what Jan Andresen and the offical liquidator gain from the termination is more dubious. For sure, the users are not gaining anything from the termination of weblin when the other option was a continuation.

There will be a real functional successor to weblin later this year. A layered virtual world on the web. It is being developed under the name Open Virtual World (currently: http://openvirtualworld.blogspot.com/). The blog has descriptions, feature lists, and a time line.

_happy_restarting()

Note: the irony in all this is, that I opposed the collection of email addresses. Weblin did not need them for the technical operation and the marketing department profited only marginally. But Jan Andresen as marketing manager nonetheless insisted on it. Now we know the real purpose of all this email collection business.

21. Juli 2009

High-tech Businesslogik bei bluehands

Am Freitag habe ich meine alte Firma bluehands in Karlsruhe besucht und ich bin sehr beeindruckt. Bluehands macht Softwareentwicklung auf hohem Niveau. Die Kernkompetenz liegt bei der Umsetzung von Projekten mit .NET für Webanwendungen, Datenbank- und Backend, sowie komplexe branchenspezifische Businesslogik. "Umsetzung" ist dabei ein zentrales Wort. Denn das beginnt bei der Planung und Denken mit und für den Kunden und endet erst wenn das System im Produktiveinsatz läuft.

Selten habe ich so "dichte", kontrollierte und hochwertige Softwareentwicklung gesehen. Die Zahl der Projekte ist beeindruckend. Die hohe Qualität bei dieser Geschwindigkeit ist nur zu halten durch Agile Entwicklungsmethoden und ständige Innovation. Mittel wie Scrum, Nightly Builds, Unit Tests, automatische Codeanalyse, Versionskontrolle, DRY, KISS, Continuous Integration sind selbstverständlich. Dazu kommen Research-Projekte, Coder-Seminar, Effizienzanalyse und interne Weiterbildung. Aktuelles Beispiel: die Clean Code Developer Initiative.

Wer also eine Visualisierungslösung braucht, z.B. im Energiebereich oder in verarbeitenden Gewerben, wie Metall und Bau, oder ein komplexes Planungstool, wer will, dass bei der Planung mitgedacht wird und, dass das System installiert wird und dann läuft, dem kann ich www.bluehands.de nur empfehlen.

Und wir anderen Coder (zumindest die meisten) können da noch was lernen. Wir sind ja auch nicht schlecht organisiert (zumindest die meisten), aber da kann man sich eine Scheibe von abschneiden. Das ist den Jungs bei bluehands selbst wahrscheinlich gar nicht so bewußt. Two thumbs up.

happy_coding()

10. Juli 2009

Abwrackprämie


Wir haben unsere alte Möhre gegen eine modernen Stadtflitzer eingetauscht. Mit einem geringen Aufpreis. Wir sind jetzt sowas von ECO.

happy_querparking();

6. Juli 2009

Metaprognose Juni 09

Von Oktober bis Mai befanden sich die Prognosen in einem linear fallenden Korridor. Aber inzwischen zeichnet sich eine Änderung der Charakteristik ab.

Nach einem weiteren Cluster von fortgesetzt pessimistischen Prognosen in April/Mai [B] hellt sich die Meinung der Institute nun etwas auf, so dass die Juni-Prognosen [C] vom linearen Verlauf abweichen und weniger schnell fallen, als noch vor 2 Monaten. Mit anderen Worten: die Prognosen werden weniger schnell schlechter, aber immer noch schlechter.

Szenarien:
- Nach den Juni-Prognosen zeichnet sich eine Stabilisierung ab: -6,5% scheint möglich nach [7]. Dafür ist aber ein sehr scharfer Knick nötig. So ein Knick ist nicht auszuschließen, wenn sich die Forschungsinstitute tatsächlich, wie vorher angedeutet in einem kollektiven Schock befanden und deshalb im Mai etwas überzogen haben. Dann wären die Krümmung nur deshalb so groß, weil die Mai-Prognosen zu steil ausgefallen sind.

- Legt man als maximal mögliche Krümmung den gleichen Absolutwert an, wie beim Absturz zwischen August und November 08, dann kann man einen Verlauf bis -7,5% erwarten [8].

Szenario [8] gilt aber nur falls es im 2. Halbjahr keine bösen Überraschungen gibt. Beruhen die aktuellen Prognosen nur auf den schlechten Zahlen des ersten Halbjahrs oder sind weitere Krisen schon eingerechnet? Als Nachfolgekrisen bieten sich an:

  • Kaufkraftverlust durch auslaufende Kurzarbeit ab Oktober. Wenn erstmal 15% arbeitslos sind, statt 5%, wird wesentlich weniger konsumiert, sicher von den betroffenen 10%, aber alle anderen sind dann auch vorsichtig. Deutsche weigern sich noch, sich persönlich betroffen zu fühlen. Wenn sich das ändert...
  • Inflation ist vielleicht das einzige Mittel mit dem die USA ihre Schulden abtragen können, wenn sie noch weiter wachsen. Im Moment sind die (öffentlichen) Schulden im Rahmen, vergleichbar den deutschen, kleiner als die japanischen und italienischen, aber wenn sie durch Konjunkturprogramme stark wachsen, könnten die USA vielleicht eine stärkere Geldentwertung dulden (oder fördern). Mit nur 10% Inflation kann man den Chinesen 200 Mrd. Dollar pro Jahr abnehmen. Das wäre der größte "Diebstahl" der Geschichte und völlig legal.
  • Deflation droht beim aktuellen Nachfrageeinbruch und kann sich selbst verstärken, wenn Nachfrage zusätzlich zurückgehalten wird, weil niedrigere Preise erwartet werden. Ob Inflation oder Deflation passiert, weiss anscheinend keiner, bzw. jeder weiss was anderes.
  • Währungskrisen und (Beinahe-)bankrotte einzelner Staaten. Kalifornien, als Nation die 8. größte Volkswirtschaft, ist zahlungsunfähig. (Das liegt auch daran, dass US-Staaten keine Schulden machen dürfen, ist also nicht ganz vergleichbar.) Aber wenn es Osteuropa richtig erwischt oder sogar Euro-Länder Irland und Griechenland, dann wird es richtig teuer, denn denen wird trotz No Bailout Klausel geholfen. Bei Euroländern drohen zwar keine Währungskrisen, aber trotzdem Zahlungsunfähigkeit durch hohe Renditeaufschläge.
  • Kreditkartenkrise oder Krisen in anderen Finanzsektoren. Vor der Subprime-Krise kannten nur wenige Subprime-Zertifikate, deren Derivate und Begleitprodukte, z.B. CDS. Vielleicht gibt es ja noch andere riskante Produktgruppen.

[7] könnte das gleiche Wunschdenken ausrücken wie [4] im Februar. Das schlechteste Szenario vom Februar [4] hat sich als viel zu optimistisch herausgestellt. Damals war eine negatives BIP Wachstum von -5% undenkbar. Genauso wie heute -10% undenkbar ist. Wenn eine größere Nachfolgekrise auftaucht, dann werden wir froh sein über nur -10%.

Da auch Dienstleistungen einschließlich staatlicher Aufgaben in das BIP einfließen, bedeutet -10%, dass ca. 25% weniger materielle Güter hergestellt werden. Mit anderen Worten: trotz der größten Krise seit 80 Jahren führen 75% der Käufer ihre Bestellungen durch und schieben Investitionen nicht auf. Man könnte auch erwarten, dass nur halb so viele gewerbliche und private Anschaffungen getätigt werden, wie letztes Jahr. Das wäre dann ein BIP von -20%. Es gibt Berichte, dass der Containerumsatz in Shanghai, dem größten Hafen der Welt, auf 30% eingebrochen ist. Das würde bedeuten, dass die Welt nur ein Drittel so viel (in China) einkauft, wie letztes Jahr. Da scheint 50% nicht so fern und 75% richtig komfortabel. Anders ausgedrückt: BIP -10% kann auch noch "richtig komfortabel" wirken.

Hoffen wir, dass das Juni-Wunschdenken [7] nicht das gleiche Schicksal erleidet, wie das Februar-Wunschdenken [4].

happy_hoping();

25. Juni 2009

Ursachenforschung bei Weblin

Ein interessanter Kommentar zur Krise von Weblin. Insgesamt liegt er nicht ganz im Ziel. Aber so wenig, wie öffentlich bekannt, ist das kein Wunder und deshalb nicht anzukreiden. Mir gefällt, dass einige Punkte wirklich diskutiert werden und man sicher davon lernen kann.

  • "Weblin hat einen Preis verliehen bekommen vom Staat bzw. Land - Das sind oft erste Warnzeichen, denn was der Staat üblicherweise toll findet ist meistens hinter der Zeit zurück."
    Nette Idee :-) aber "der Zeit hinterher" ist unwahrscheinlich. Eher zu früh und noch nicht Mainstream genug. Ein Wunder, dass es einen Preis gab.

  • "Bis zum Schluss gab es keine Lösung, die ohne zusätzliche Softwareinstallation lief - Jeder weiß, dass zusätzliche SW-Installationen eine hohe EInstiegsbarriere für neue Nutzer sind, zumal es von anderen Anbietern Lösungen als Firefox-Plugin gab, die ihren Zweck erfüllten."
    Die gut alte Download Hürde, immer wieder gerne kolportiert, aber durch die Praxis widerlegt. 3 Mio registrierte und 150.000 Weekly Returning User für relativ wenig Marketingausgaben sagen etwas anderes. Im ernst: Benutzer im zweistelligen Prozentbereich machen den Download, werden und bleiben Weblin-User, manchmal sogar bis 30% (der Besucher auf der Weblin-Seite), was eine ziemlich gute Conversion-Rate ist.

  • "Das Modell mit “virtuellem Nippes” Geld zu verdienen schien mir äußerst zweifelhaft - Ich hab es ja selbst ausprobiert, mehr als ein kurzfristiger Unterhaltungseffekt war nicht drin, danach nervt es nur noch, genau wie RocketOn."
    Virtuelle Güter im Allgemeinen scheinen zu gehen, wie viele Berichte (auch in diesem Blog) zeigen. Aber bei Weblin war das alles ziemlich lange ziemlich sinnlos, also "Nippes", stimmt. Das hätte man nicht so lange sinnlos bleiben lassen dürfen. Ende 2007 wurden virtuelle Güter eingeführt, dann kamen schnell die Weihnachts- und Horten-Sammelaktionen. Dann hat Weblin leider die die virtuellen Gütern nicht weiter entwickelt. Man konnte sammeln, tauschen, ein paar Alben machen für Avatare. Gegen Ende dann die Effekte. Aber eine Ökonomie hat es nie gegeben. Die User wurden ein ganzes Jahr hängen gelassen. Das Jahr 2008 wurde komplett verpasst, weil die Prioritäten falsch waren. Später mehr dazu...

  • "Die Lösung schien mir viel zu invasiv bzw. aufdringlich, sie stellte sich selbst in den Vordergrund, denn im wahrsten Sinn des Wortes standen die Avatare und nicht die Webseite im Vordergrund."
    Das ist ein interessanter Punkt, der sicher noch ausführlich diskutiert werden wird. Ich glaube Weblin ist minimal-invasiv (siehe Vortrag Virtual Worlds Camp). Ob es minimal- oder maximal-invasiv ist, darüber lässt sich trefflich streiten. Grundsätzlich vergleicht sich Weblin gerne mit der realen Welt. Stehen auf der realen Straße, die Menschen (Avatare) zu sehr im Vordergrund? Oder sollten die Schaufenster (Webseite) mehr hervortreten? Aber man kann hier sicher was lernen. Sollten die Avatare nur 20 Pixel hoch sein? Nur in der Statusleiste vom Browser? Nur auf Knopfdruck sichtbar? 100 Pixel, aber transparent? Oder etwas ganz anderes?

  • "Mit das größte Problem schien mir, dass man nur wenn man EXAKT auf der selben URL wie ein anderer Besucher im Web war, auch jemanden gesehen hat. Dieser Tunnelblick hilft mir nicht! Die Menschen in der Stadt erst dann zu sehen, wenn ich in jeden einzelnen Laden hineingehe (dann aber alle anderen nicht mehr zu sehen), wäre ein recht armes Erleben von sozialem Raum."
    Die Topologie im web ist wirklich eins der größten Probleme. Groß im Sinne von interessant, nicht im Sinne von riskant. Bei machen Systemen gilt wirklich der ganze URL, bei anderen immer nur die Domain. Bei Weblin ist es konfigurierbar. Standardmäßig gilt der Domainname des Servers, wobei www. abgetrennt wird. Aber man kann das auch viel genauer einstellen bis auf ein Raum pro Zeitungsartikel oder pro Youtube-Video.
    Die Bemerkung könnte sich auch darauf beziehen, dass man inhaltliche Nachbarschaft verwenden sollte, nicht nur die technische Adresse (URL). Das hat Me.dium versucht und wieder beendet. Damit ist das Rennen aber nicht entschieden. Ob Inhalt besser funktioniert als Adresse wird sich zeigen. Sicher ist, dass es für eine Firma (außer Google) schwierig ist, allen Websites Kategorien zuzuordnen. Vielleicht geht es mit Crowd-Sourcing indem die User Kategorien zu Websites festlegen und danach wird bestimmt, wer wen sieht.
    Vielleicht soll auch die Nachbarschaft einbezogen werden. Dann würde man auch die die Leute auf der Straße sehen wenn man "im Laden" steht. Auch das gab es schon mal bei CoBrow, wurde aber wegen der Komplexität der Nachbarschaftsberechung über Hypertext-Links fallen gelassen.

  • "Nutzer von Webseiten wollen nicht bei ihrer primären Tätigkeit (Surfen im Web) gestört werden, wenn also Präsenztechnologie ins Spiel kommt, darf sie keinesfalls derart invasiv sein, den Nutzer bei seiner Tätigkeit zu behindern. Große Avatare stören da aber nur. Am besten bringt das für mich folgender Beitrag bei Beat Doebli auf den Punkt: Why dots? mit dem zugehörigen YouTUBE-Video."
    Hm, ich bin kein Punkt. Ich will mich individualisieren. In vielen virtuellen Welten funktioniert das Avatar, meistens sogar in 3rd Person, d.h. es verdeckt einen Teil der Umgebung. Man kann argumentieren, dass das Web keine virtuelle Welt ist, weil der Zweck ein Anderer ist. Aber vielleicht wollen die Benutzer trotzdem individualisieren und Freunde zu wiedererkennen. Gibt es eine Möglichkeit, den Inhalt nicht mit dem Avatar zu verdecken, aber trotzem zu individualisieren? Ich bin gespannt.

  • "Besucher von Webseiten wollen u.U. gern weiterhin anonym bleiben. Nicht jeder möchte beim Besuch bestimmter Seiten “gesehen werden” bzw. indentifiziert werden, oder gar seinen Besuch mit seiner Identität verknüpft in einer Datenbank eines Präsenztechnologieanbieters wissen."
    Ja. Das ist ein großes Problem vieler Präsenztechnologien. Die meisten Systeme haben einen Anbieter, der die URLs ALLER Benutzer bekommt und vielleicht speichert. Mal davon abgesehen, dass Alexa-Benutzer das seit Jahren gerne machen, finde ich es nicht gut. URLs dürfen nicht den Rechner des Benutzers verlassen. Deshalb wurde URL-Mapping im Client entwickelt.
    Trotzdem wird natürlich angezeigt, dass jemand da ist, aber nur in dem Maße, wie Benutzer es wollen. Man kann mit einem komplett künstlichen, anonymen Profil auf dem Web spazieren gehen. Das ist viel anonymer als in der realen Welt.

  • "Webseitenbetreiber möchten nicht, dass an ihnen “vorbei” kommuniziert wird, ohne dass sie “dabei” sein können. Niemand wird eine Präsenztechnologie unterstützen, bei der er nicht wirksam selbst Einfluss nehmen kann als Seitenbetreiber."
    Das ist ein sehr interessanter und richtiger Punkt. Die Menschen, Webseitenbetreiber und Benutzer müssen sich beteiligen können. Dazu wird es sicher in Zukunft noch viele gute Ideen geben. Bisher umgesetzt ist die Möglichkeit für Webseitenbetreiber, das "Hausrecht" auszuüben indem sie bestimmen wo gechattet wird. Der Webseitenbetreiber kontrolliert den Chatraum und kann damit sowohl moderieren und kontrollieren, als auch die Präsenz durch Zusatzdienste erweitern.
    Bei Weblin gibt es noch weblin Sitekit. Damit kann der Webseitenbetreiber den Client steuern und Erweiterungen auf seiner Seite anbieten.
Mehr "Social Technology" ist vermutlich hilfreich, die Verweildauer zu erhöhen. Dazu gehört vielleicht Notizen hinterlassen, sehen wer in der Vergangenheit da war, vielleicht Interaktion mit der Webseite und Interaktion zwischen Benutzern über die Webseite (siehe weblin Sitekit). Man kann sogar die Verweildauer des "einsamen Surfers" erhöhen wenn man ihm/ihr etwas zu tun gibt im Layer über dem Web. Und sicher kann man Besucher mehr beschäftigen, wenn sie gemeinsam etwas zu tun haben wie hier: cooperation and collective activity as socializing browsing.

happy_socializing();

PS: Als Advocatus Diaboli könnte man allerdings auch sagen: WTF soll das ständige Socializing. Virtuelle Präsenz zeigt Leute und lässt sie kommunizieren. Der Rest ergibt sich von selbst, wie in der realen Welt. Basta.

20. Juni 2009

Are we witnessing the birth of infosocialism?

Infosocialism was originally a philosophy created by David Pulver, Jon F. Zeigler and Sean Punch for the Transhuman Space role-playing game.

The core of infosocialism is the observation, that information is very different from material goods in that it can be given away without the former holder losing anything. The notion of "intellectual property", however, often leads to injustice, more than omitting it altogether. Therefore, infosocialism claims, that "information wants to be free".

David Pulver introduces infosocialism in 2034. But it looks like we are witnessing the birth of a similar movement in the real world now. In 2006 the "Pirate Party" was founded in Sweden. It strives to reform laws regarding copyright and patents. The party got 7% of the total Swedish votes in the 2009 European Parliament elections. Pirate parties have been founded in several other countries.

The agenda also includes the strengthening of privacy rights and the freedom of information. These ideas are key factors in the movement against internet censorship in Germany, where the government passed a law to establish a censorship infrastructure with the combined votes of the grand-coalition between the German social democrats and conservative party. The law is made to for a very good cause. However, german activists and opposition parties claim, that the methods planned by the government are as well insufficient for the cause as they are threatening to privacy and the freedom of information.

The german pirate party got 0.9% in the European elections. If the topic remains active for three more months, then there is a good chance, that the german pirate party gains several percent in the general elections. Many voters of the traditional left-wing anti-establishment party, the greens, do not feel represented, since many green representatives abstained from voting on the internet censorship architecture law. Pirate parties are supported primarily by a technophile, young, well educated, middle class electorate. A good match.

40 years ago, the green movement emerged with an environmental agenda. It was then strengthened by the opposition against nuclear power during the 1970s. Later it went mainstream with a much broader environmental, left-wing, yet middle-class program. We might be seeing similar development, where "pirate parties" start with an anti intellectual property agenda, then activate people with privacy issues. Later the movement might turn into a more general infosocialism which includes copyright/patent issues, privacy, and transparency. In a modern society, where information is the most valuable factor, these issues may influence our life more than we currently think.

happy_moving();

18. Juni 2009

Population explosion for virtual worlds

There are VCs, business angels, and investors who think, that the quick and big money is in ads for virtual worlds.

There are also other voices who expect microtransactions to grow sharply over the next years.

This report at least predicts:

"86% of revenue in 2015 will come from microtransactions -- this equates to a growth from 2008's microtransaction figure of roughly $1 billion, to $17.3 billion in six years time."

It will be interesting to watch how things turn out. Maybe ads can swing up to the same performance.

happy_disbelieving()

9. Juni 2009

What Are The Rewards Of Free-To-Play MMOs?

Nachtrag zu meinem Vortrag beim Virtual Worlds Camp: dieser Artikel bei Gamasutra nennt die gleichen Zahlen für ARPU in Free 2 Play MMOs und Browsergames.

Der ARPU liegt "from 30 cents up to $2", je nach Gameplay und Stärke des Engagements der User: "Sports and gambling games tend to be a bit higher, social games a bit lower."

"[Revenue] typically comes from 5-10% of the total number of users in any given month"

Na bitte. Meine Rede. Genau so stand es in unserem Businessplan. Realistisch aber immer etwas auf der konservativen Seite.

_happy_gambling();

5. Juni 2009

Listen to Engineering

This is a corporate culture I like:

"Palantir runs a tight ship, providing vital information on an internal wiki, keeping meetings concise and striving to hire candidates with “an engineering mindset, even in our administrative people,” McGrew says.

The division of the company devoted to government products has only one ten-minute meeting every week to make sure developers and managers are on the same page and to discuss prospective customers. There is also a company policy against using PowerPoint decks.

The company is also unique in that it doesn’t have any soft-skills marketing or sales personnel. All customer-facing employees have degrees in computer science or symbolic systems and are capable of walking customers through software installations and debugging. This has helped Palantir build tighter relationships with its clients."

We are in a technology business. Technology is king. Engineering knows what to do. Of course many other people also know and we need their input. But if engineering fails to know, then the company is doomed anyway. No technology agnostic, smart ass business developer, investor relations, sales driven product management can save it then. It's the technology, stupid. Get over it.

To hell with your "how to manage companies the old way" books. To hell with "IT is a service department". To hell with your "great managers who sell bad decisions for good, because they once though they were good and can not admit that they turned out bad".

This is technology and you listen to us!

You don't believe me, because I am just a techie? Maybe you believe IMVU or Toyota: http://startuplessonslearned.blogspot.com/2008/11/sciencedaily-corporate-culture-is-most.html

happy_listening()

3. Juni 2009

Galactic Developments: Open Source Science Fiction Projekt

Habe meine Website Galactic Developments gründlich runderneuert und vom alten Frameset-Design auf ein templatebasiertes CMS umgestellt.

(Ich weiss, eigentlich nicht der Rede wert.)

Ursprünglich wollte ich den Inhalt auf einen Blog umziehen, wegen den automatischen Web20 Features, aber seitdem Suchmaschinen Blogs runter-gewichten wird eine eigene Site wieder sexy. Also bitte: http://www.galactic-developments.de

_happy_renovating()

27. Mai 2009

Concurrent Casual - Virtuelle Güter im Web

Mein Vortrag beim Virtual Worlds Camp. Das VWC war angeschlossen an die Webinale und hatte den Themen-Schwerpunkt "Virtuelle Welten und virtuelle Güter".





happy_presenting()

24. Mai 2009

Reverse Engineering Requirements from Solutions

I just read an article about Planning For Fun In Game Programming. It starts with a discussion of requirements and solutions. The essential is:

"It can be compelling to write solutions instead of requirements. It is tempting to design a solution to a requirement at the same time as writing the requirement -- especially the interesting ones! Writing solutions feels more authoritative, more formal, more precise and more accurate. But it is counterproductive. By prescribing a given solution, we preclude any potential superior solutions. Prescribing solutions also limits our understanding of the problem domain and intent of the requirement."

This is so true.

Programmers and especially lead developers work by requirements. The lead developers plans and the programmer implements to meet the requirements. But very often the so called requirement paper comes as a series of solutions. Business development, product management, sales, and marketing know what users need. They offer their advice about the next killer feature or the next product in form of requirements papers. Sometimes they even explain in detail what needs to be implemented with examples. This is the point where requirements turn into proposed solutions. This is done in good faith, but with the risk as described in the article above.

My favourite example is:

Cast:
Development (a lead developer)
Marketing (any other non-technical person)

Marketing: "can we add a cookie?"
Development: "yes, we can."
Marketing: "... and then we can always recognize a user?"
Development: "wait, do you want a cookie or do you want to recognize the user?"
Marketing: "recognize the user!"
Development: "but you said cookie."
Marketing: "It thought this is the same."
Development: "Not in our case, because this is not a Web application."

This is a short example, solved in 2 minutes. But the same problem can easily waste weeks of development time in more serious cases. Whatever Development gets, it is always the task of Development to understand the problem, not the proposed solution. If Development slavishly implements a proposed solution and it turns out to be the wrong solution, then it is the fault of Development.

Marketing tries to specify problems as good as it can. If it is very good, then we (Development) get a requirements document. Otherwise we get solutions. Usually we get a mixture, which is the best case. But we must not fall victim to proposed solutions and examples.

Whatever we get, it is our responsibility to "reverse engineer" the problem. To find out what they really want in order to produce the optimal result. We must not hide behind "their" requirements document and just do. Proposed solutions are just a tool to understand the real problem. It is our job, because we can.

happy_backtracking()