<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>DenkZEIT</title>
	<atom:link href="http://blog.gungfu.de/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.gungfu.de</link>
	<description>leaving explanation to those who prefer comfort to truth</description>
	<lastBuildDate>Fri, 04 May 2012 15:08:55 +0000</lastBuildDate>
	<language>de</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Neues Zitat: kreativer Geschmack</title>
		<link>http://blog.gungfu.de/archives/2012/05/04/neues-zitat-kreativer-geschmack/</link>
		<comments>http://blog.gungfu.de/archives/2012/05/04/neues-zitat-kreativer-geschmack/#comments</comments>
		<pubDate>Fri, 04 May 2012 15:08:24 +0000</pubDate>
		<dc:creator>Steffen</dc:creator>
				<category><![CDATA[Unsortiertes]]></category>
		<category><![CDATA[kreativität]]></category>
		<category><![CDATA[können]]></category>
		<category><![CDATA[zitate]]></category>

		<guid isPermaLink="false">http://blog.gungfu.de/?p=2591</guid>
		<description><![CDATA[When you don’t create things, you become defined by your tastes rather than ability. Your tastes only narrow &#38; exclude people. So create. (Internetquelle)]]></description>
			<content:encoded><![CDATA[<blockquote><p>When you don’t create things, you become defined by your tastes rather than ability. Your tastes only narrow &amp; exclude people. So create.</p></blockquote><cite>  <a href="http://metaphysicaldeveloper.wordpress.com/2012/04/20/conjcraft-a-minecraft-mod-implemented-in-clojure/" class="source">(Internetquelle)</a></cite>]]></content:encoded>
			<wfw:commentRss>http://blog.gungfu.de/archives/2012/05/04/neues-zitat-kreativer-geschmack/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Aikido in der New Yorker U-Bahn</title>
		<link>http://blog.gungfu.de/archives/2012/04/25/aikido-in-der-new-yorker-u-bahn/</link>
		<comments>http://blog.gungfu.de/archives/2012/04/25/aikido-in-der-new-yorker-u-bahn/#comments</comments>
		<pubDate>Wed, 25 Apr 2012 19:03:09 +0000</pubDate>
		<dc:creator>Steffen</dc:creator>
				<category><![CDATA[Unsortiertes]]></category>
		<category><![CDATA[Aikido]]></category>
		<category><![CDATA[Clips]]></category>

		<guid isPermaLink="false">http://blog.gungfu.de/?p=2588</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<iframe width="420" height="315" src="http://www.youtube.com/embed/Erlw-ODVZxU" frameborder="0" allowfullscreen></iframe>]]></content:encoded>
			<wfw:commentRss>http://blog.gungfu.de/archives/2012/04/25/aikido-in-der-new-yorker-u-bahn/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mit Emacs (und Tramp und Leiningen und Noir) in den Webentwicklungsflow kommen</title>
		<link>http://blog.gungfu.de/archives/2012/02/14/mit-emacs-und-tramp-und-leiningen-und-noir-in-den-webentwicklungsflow-kommen/</link>
		<comments>http://blog.gungfu.de/archives/2012/02/14/mit-emacs-und-tramp-und-leiningen-und-noir-in-den-webentwicklungsflow-kommen/#comments</comments>
		<pubDate>Tue, 14 Feb 2012 14:51:51 +0000</pubDate>
		<dc:creator>Steffen</dc:creator>
				<category><![CDATA[Unsortiertes]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[emacs]]></category>
		<category><![CDATA[noir]]></category>
		<category><![CDATA[slime]]></category>
		<category><![CDATA[swank]]></category>
		<category><![CDATA[tramp]]></category>

		<guid isPermaLink="false">http://blog.gungfu.de/?p=2576</guid>
		<description><![CDATA[Meine gegenwärtige Entwicklungsumgebung sieht so aus, dass ich das bereits vorgestellte Screen nutze, um den Jetty-Server laufen zu lassen. Mittels Tramp ändere ich in meinem lokal laufenden Emacs die Source-Dateien auf dem Server. Noir sorgt automatisch dafür, dass die Änderungen sofort (d.h. nach einem Browserrefresh) sichtbar werden. Man kann natürlich alles direkt am Server entwicklen. [...]]]></description>
			<content:encoded><![CDATA[<img src="http://blog.gungfu.de/wp-content/uploads/2012/02/200px-Clojure-glyph.svg.png" alt="" title="Clojure Glyph" width="200" height="210" class="alignright size-full wp-image-2577" />

<p>Meine gegenwärtige Entwicklungsumgebung sieht so aus, dass ich <a href="http://blog.gungfu.de/archives/2012/01/09/neues-tool-in-meinem-web-stack-gnu-screen/">das bereits vorgestellte Screen</a> nutze, um den Jetty-Server laufen zu lassen.</p>

<p>Mittels <a href="http://wiki.gungfu.de/Main/EmacsTramp">Tramp</a> ändere ich in meinem lokal laufenden Emacs die Source-Dateien auf dem Server.</p>

<p><a href="http://webnoir.org/">Noir</a> sorgt automatisch dafür, dass die Änderungen sofort (d.h. nach einem Browserrefresh) sichtbar werden.</p>

<p>Man kann natürlich alles direkt am Server entwicklen. Dazu fehlt mir allerdings die entsprechende Emacs-Installation am Server. Und ohne die will ich nicht.</p>

<p>Was aber noch zusätzlich geht ist <a href="https://github.com/technomancy/swank-clojure"><code>lein swank</code></a> in einer zusätzlichen shell-Session am Server zu starten. Dann kann man mit einem lokal laufenden Emacs per <a href="http://wiki.gungfu.de/Main/SLIME">slime</a> auf diesen Swank-Server zugreifen. Der Aufruf, mit dem ich das schon erfolgreich versucht habe ist <code>lein swank 4005 0.0.0.0</code> &#8211; damit lauscht swank an allen Adressen auf Port 4005. Aus Sicht der Security ist das sicherlich sehr problematisch, denn es gibt keine Passwortabfrage und soweit ich das ermitteln konnte, gibt es auch keine Kontrolle des ssh-Schlüssels. (Falls hier jemand einen Verbesserungsvorschlag hat: Her damit!)</p>

<p>Da jetzt der Web-Server und <a href="http://stackoverflow.com/questions/2285437/a-gentle-tutorial-to-emacs-swank-paredit-for-clojure">swank</a> gleichzeitig laufen, kann man in der Swank-Session Anwendungsteile direkt am Server in einer <a href="http://wiki.gungfu.de/Main/ReadEvalPrint">REPL</a> testen (z.B. Datenbankzugriff mit dem produktiven Datenbestand). Wenn man eine source-Datei per Tramp auf den Server nach erfolgreichem Testen zurückschreibt, übernimmt Noir automatisch diese Änderungen.<br />
Man sollte ein wenig darauf aufpassen, dass man eine Source-Datei nicht in einem inkonsistenten, slime/REPL-getriebenen Zustand auf den Server speichert. Aber im Entwicklunsbetrieb ist das auch nicht wirklich ein Problem.</p>


<p>Es ergibt sich eine Entwicklung &#8220;am lebenden Objekt&#8221; und eine sehr kurze (vielleicht schon <a href="http://blog.gungfu.de/archives/2011/12/04/minimal/">minimale</a>) Entwicklungsschleife.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.gungfu.de/archives/2012/02/14/mit-emacs-und-tramp-und-leiningen-und-noir-in-den-webentwicklungsflow-kommen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TIOBE: Clojure in Top 100 &#8211; genauer: Platz 77</title>
		<link>http://blog.gungfu.de/archives/2012/02/14/tiobe-clojure-in-top-100-genauer-platz-77/</link>
		<comments>http://blog.gungfu.de/archives/2012/02/14/tiobe-clojure-in-top-100-genauer-platz-77/#comments</comments>
		<pubDate>Tue, 14 Feb 2012 11:37:09 +0000</pubDate>
		<dc:creator>Steffen</dc:creator>
				<category><![CDATA[Unsortiertes]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[conj]]></category>
		<category><![CDATA[Programmiersprachen]]></category>
		<category><![CDATA[tiobe]]></category>

		<guid isPermaLink="false">http://blog.gungfu.de/?p=2573</guid>
		<description><![CDATA[Via disclojure habe ich mitbekommen, dass Clojure die Top 100 der unter TIOBE aufgeführten Programmiersprachen erreicht hat und auf Platz 77 gelandet ist. Außerdem gibt sind einige Reden der Conj 2011 online: http://clojure.com/blog/2012/01/31/first-conj-2011-videos-available.html http://clojure.com/blog/2012/02/06/more-conj-2011-videos-available.html]]></description>
			<content:encoded><![CDATA[<img alt="clojures logo" src="http://wiki.gungfu.de/uploads/Main/clojure-icon.gif" title="clojures logo" class="alignright" width="100" height="100" />

<p><a href="http://disclojure.org/2012/02/08/intertweets/">Via disclojure</a> habe ich mitbekommen, dass <a href="http://wiki.gungfu.de/Main/Clojure">Clojure</a> die Top 100 der unter TIOBE aufgeführten Programmiersprachen erreicht hat und auf Platz 77 gelandet ist.</p>

<p>Außerdem gibt sind einige Reden der <a href="http://clojure-conj.org/">Conj 2011</a> online:</p>
<ul>
	<li><a href="http://clojure.com/blog/2012/01/31/first-conj-2011-videos-available.html">http://clojure.com/blog/2012/01/31/first-conj-2011-videos-available.html</a></li>
	<li><a href="http://clojure.com/blog/2012/02/06/more-conj-2011-videos-available.html">http://clojure.com/blog/2012/02/06/more-conj-2011-videos-available.html</a></li>
</ul>




]]></content:encoded>
			<wfw:commentRss>http://blog.gungfu.de/archives/2012/02/14/tiobe-clojure-in-top-100-genauer-platz-77/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mechanismen einer gelungenen Karriere erklärt: Das Peter Prinzip</title>
		<link>http://blog.gungfu.de/archives/2012/01/30/mechanismen-einer-gelungenen-karriere-erklart-das-peter-prinzip/</link>
		<comments>http://blog.gungfu.de/archives/2012/01/30/mechanismen-einer-gelungenen-karriere-erklart-das-peter-prinzip/#comments</comments>
		<pubDate>Mon, 30 Jan 2012 19:53:22 +0000</pubDate>
		<dc:creator>Steffen</dc:creator>
				<category><![CDATA[Unsortiertes]]></category>
		<category><![CDATA[Clips]]></category>
		<category><![CDATA[job]]></category>
		<category><![CDATA[management]]></category>

		<guid isPermaLink="false">http://blog.gungfu.de/?p=2537</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<iframe width="420" height="315" src="http://www.youtube.com/embed/2r_u1F3IQNU" frameborder="0" allowfullscreen></iframe>]]></content:encoded>
			<wfw:commentRss>http://blog.gungfu.de/archives/2012/01/30/mechanismen-einer-gelungenen-karriere-erklart-das-peter-prinzip/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Aikido Yoshinkan in Wolframs-Eschenbach: Anfängerkurs hat begonnen!</title>
		<link>http://blog.gungfu.de/archives/2012/01/26/aikido-yoshinkan-in-wolframs-eschenbach-anfangerkurs-hat-begonnen/</link>
		<comments>http://blog.gungfu.de/archives/2012/01/26/aikido-yoshinkan-in-wolframs-eschenbach-anfangerkurs-hat-begonnen/#comments</comments>
		<pubDate>Thu, 26 Jan 2012 19:40:16 +0000</pubDate>
		<dc:creator>Steffen</dc:creator>
				<category><![CDATA[Unsortiertes]]></category>
		<category><![CDATA[Aikido]]></category>
		<category><![CDATA[dojo-sochin]]></category>

		<guid isPermaLink="false">http://blog.gungfu.de/?p=2532</guid>
		<description><![CDATA[Diese Woche war das zweite Training &#8211; die Matte ist immer noch voll.]]></description>
			<content:encoded><![CDATA[<img src="http://www.dojo-sochin.de/images/2012_01_17_Startseite_IMG_9456_small.jpg" alt="Gruppe beim Grüßen" class="imgR" />

Diese Woche war das zweite Training &#8211; <a href="http://www.dojo-sochin.de/bilder/dojo/dojo/aikido-anfaengerkurs-am-17012012.html">die Matte ist immer noch voll</a>. <img src='http://blog.gungfu.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> ]]></content:encoded>
			<wfw:commentRss>http://blog.gungfu.de/archives/2012/01/26/aikido-yoshinkan-in-wolframs-eschenbach-anfangerkurs-hat-begonnen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>In 8 Schritten zur Web-App mit Clojure</title>
		<link>http://blog.gungfu.de/archives/2012/01/26/in-8-schritten-zur-web-app-mit-clojure/</link>
		<comments>http://blog.gungfu.de/archives/2012/01/26/in-8-schritten-zur-web-app-mit-clojure/#comments</comments>
		<pubDate>Thu, 26 Jan 2012 19:36:37 +0000</pubDate>
		<dc:creator>Steffen</dc:creator>
				<category><![CDATA[Unsortiertes]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[leiningen]]></category>
		<category><![CDATA[noir]]></category>
		<category><![CDATA[Webentwicklung]]></category>

		<guid isPermaLink="false">http://blog.gungfu.de/?p=2525</guid>
		<description><![CDATA[In meinem Staunen, wie schnell man eine Clojure-Web-Anwendung am Laufen hat, habe ich an einem unbedarften Rechner mal ausprobiert, wie schnell das wirklich geht. Quasi von &#8220;Java ist installiert&#8221; bis &#8220;Clojure-Web-Anwendung läuft&#8221;. Zum Einsatz kommt das Clojure-Web-Framwork Noir. Folgende Schritte sind (unter Windows) dazu nötig &#8211; der ganze Ablauf dauert vielleicht 10 Minuten: Verzeichnis anlegen, [...]]]></description>
			<content:encoded><![CDATA[<img alt="clojures logo" src="http://wiki.gungfu.de/uploads/Main/clojure-icon.gif" title="clojures logo" class="alignright" width="100" height="100" />

<p>In meinem Staunen, wie schnell man eine Clojure-Web-Anwendung am Laufen hat, habe ich an einem unbedarften Rechner mal ausprobiert, wie schnell das wirklich geht. Quasi von &#8220;<a href="http://www.java.com/de/download/">Java ist installiert</a>&#8221; bis &#8220;Clojure-Web-Anwendung läuft&#8221;. Zum Einsatz kommt das Clojure-Web-Framwork <a href="http://webnoir.org/">Noir</a>.</p>


<p>Folgende Schritte sind (unter Windows) dazu nötig &#8211; der ganze Ablauf dauert vielleicht 10 Minuten:</p>


<ol>
<li>
<p>Verzeichnis anlegen, in das alle Clojure-Sachen kommen sollen. Zu Referenzzwecken nenne ich es ROOT.</p>
</li>
<li>
<p><a href="https://github.com/technomancy/leiningen">Leiningen</a>: das Skript <code>lein.bat</code> runterladen und in ROOT ablegen.</p>

<p>Leiningen ist ein (inzwischen <i>das</i>?) Dependency-Management- und Buildtool für Clojure.</p>
</li>
<li>
<p>Ebenso mit <a href="http://users.ugent.be/~bpuype/wget/">wget</a> verfahren: Runterladen und ins ROOT-Verzeichnis legen.</p>

<p>wget wird von Leiningen benötigt um Abhängigkeiten selbst aus dem Web runterladen zu können.</p>
</li>
<li>
<p>Jetzt eine Kommandozeile in ROOT öffnen und <code>lein self-install</code> eingeben.</p>

<p>Leiningen installiert sich jetzt selbst, d.h. es lädt zwei oder drei JARs aus einem MAVEN-Repository und packt diese in ein dafür angelegtes Verzeichnis <code>%HOME%\.lein</code>.</p>
</li>
</ol>

<p>Nach diesen drei Schritten hat man alles so eingerichtet, dass man mit der clojure-Entwicklung loslegen kann. Mittels Leiningen könnte man jetzt ein normales Projekt anlegen: lein new my-project. Aber wir wollen noch ein bisschen mehr.</p>

<ol start="5">
<li>
<code>lein plugin install lein-noir 1.2.1</code>

<p>Jetzt geht&#8217;s Richtung Webentwicklung: Es wird ein Plugin für Leiningen installiert: <code>lein-noir</code></p>
</li>
<li>
<code>lein noir new my-website</code>

<p>Dieser Aufruf erzeugt erstmal ein Leiningen-Projekt. Dieses Projekt beinhaltet aber bereits die beispielhafte Noir-Anwendung&#8230;</p>
</li>
<li>
<code>cd my-website</code>

<p>Es wird ins Projektverzeichnis gewechselt, damit für Leiningen klar ist, mit welchem Projekt zu arbeiten ist.</p>
</li>
<li>
<code>../lein run</code>

<p>&#8230;startet die Noir-Anwendung. Ab jetzt lauscht ein <a href="http://www.eclipse.org/jetty/">Jetty</a>-Server auf Port 8080 am <code>localhost</code> auf eingehende Browser-Anfragen: <a href="http://localhost:8080/">http://localhost:8080/</a>.</p>
</li>
</ol>


<h3>Noch ein paar Anmerkungen</h3>

<p>In der <code>project.clj</code>-Datei, die sich unter my-website befindet, werden die Abhängigkeiten für Leiningen verwaltet. D.h. hierdurch bekommt Leiningen raus, welche JARs aus den zentralen MAVEN-Repositories zu laden sind.<br />Die <code>project.clj</code>-Datei bietet noch <a href="https://github.com/technomancy/leiningen/blob/master/sample.project.clj">einige Einstellungsmöglichkeiten mehr</a> für Leiningen und die zu startende JVM. Das sei hier aber nur im Vorbeigehen erwähnt.</p>

<p>Zu Beginn (es wurden schon zwei Abhängigkeiten für den Zugriff auf eine <a class="wikiLink" href="http://wiki.gungfu.de/Main/MySql">MySql</a>-Datenbank hinzugefügt) sieht die project-Datei folgendermaßen aus:</p>

<div id="wpshdo_1" class="wp-synhighlighter-outer"><div id="wpshdt_1" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_1"></a><a id="wpshat_1" class="wp-synhighlighter-title" href="#codesyntax_1"  onClick="javascript:wpsh_toggleBlock(1)" title="Click to show/hide code block">Code block</a></td><td align="right"><a href="#codesyntax_1" onClick="javascript:wpsh_code(1)" title="Show code only"><img border="0" style="border: 0 none" src="http://blog.gungfu.de/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_1" onClick="javascript:wpsh_print(1)" title="Print code"><img border="0" style="border: 0 none" src="http://blog.gungfu.de/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://blog.gungfu.de/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://blog.gungfu.de/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_1" class="wp-synhighlighter-inner" style="display: block;"><pre class="clojure" style="font-family:monospace;"><span class="br0">&#40;</span>defproject gungfu <span class="st0">&quot;0.1.0-SNAPSHOT&quot;</span>
            :<span class="me1">description</span> <span class="st0">&quot;FIXME: write this!&quot;</span>
            :<span class="me1">dependencies</span> <span class="br0">&#91;</span><span class="br0">&#91;</span>org<span class="sy0">.</span>clojure<span class="sy0">/</span>clojure <span class="st0">&quot;1.3.0&quot;</span><span class="br0">&#93;</span>
                           <span class="br0">&#91;</span>noir <span class="st0">&quot;1.2.1&quot;</span><span class="br0">&#93;</span>
&nbsp;
                           <span class="br0">&#91;</span>org<span class="sy0">.</span>clojure<span class="sy0">/</span>java<span class="sy0">.</span>jdbc <span class="st0">&quot;0.1.1&quot;</span><span class="br0">&#93;</span>
                           <span class="br0">&#91;</span>mysql<span class="sy0">/</span>mysql<span class="sy0">-</span>connector<span class="sy0">-</span>java <span class="st0">&quot;5.1.18&quot;</span><span class="br0">&#93;</span><span class="br0">&#93;</span>
            :<span class="me1">main</span> gungfu<span class="sy0">.</span>server<span class="br0">&#41;</span></pre></div></div>


<p>Toll ist, dass mit <code>../lein repl</code> eine REPL gestartet werden kann, mit der man entweder direkt die Webanwendung programmiert oder erstmal ein paar Experimente in Sachen Clojure unternehmen kann.</p>

<p>Um Leiningen von überall starten zu können, ohne das lästige <code>../</code> eingeben zu müssen, sollte man den Pfad zu Leiningen in die Umgebungsvariable <code>PATH</code> aufnehmen. Man kann <code>lein.bat</code> zuvor auch in ein dafür geeignetes Verzeichnis verschieben. Das Skript verträgt das. <img src='http://blog.gungfu.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>

<p>Bei Änderungen an Source-Dateien im Noir-Projekt sorgt Noir automatisch dafür, dass diese nachgeladen werden. D.h. der Server muss nicht neu gestartet werden, um Änderungen zu sehen.</p>

<p>Die Erklärungen auf der Noir-Homepage sind so kompakt, dass man anhand dieses Materials schnell eine eigene kleine Web-Anwendung zusammenschustern kann.</p>

<p>Viel Spaß dabei&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gungfu.de/archives/2012/01/26/in-8-schritten-zur-web-app-mit-clojure/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wieder online: HolonWiki</title>
		<link>http://blog.gungfu.de/archives/2012/01/18/wieder-online-holonwiki/</link>
		<comments>http://blog.gungfu.de/archives/2012/01/18/wieder-online-holonwiki/#comments</comments>
		<pubDate>Wed, 18 Jan 2012 20:05:49 +0000</pubDate>
		<dc:creator>Steffen</dc:creator>
				<category><![CDATA[Unsortiertes]]></category>
		<category><![CDATA[diplomarbeit]]></category>
		<category><![CDATA[Holonen]]></category>
		<category><![CDATA[wiki]]></category>

		<guid isPermaLink="false">http://blog.gungfu.de/?p=2515</guid>
		<description><![CDATA[[svg src="http://holon.gungfu.de/wiki/uploads/Main/holarchy.png" width="300" height="300" style="float:right; margin:auto;" type="embed"] Nachdem ich letzte Woche feststellen musste, dass das HolonWiki nicht mehr funktionierte, habe ich es jetzt wieder zum Laufen bekommen. War eine PHP-Einstellungssache. Daher &#8211; zur Erinnerung &#8211; der Link dorthin: http://holon.gungfu.de/wiki/]]></description>
			<content:encoded><![CDATA[[svg src="http://holon.gungfu.de/wiki/uploads/Main/holarchy.png" width="300" height="300" style="float:right; margin:auto;" type="embed"] 

Nachdem ich letzte Woche feststellen musste, dass das <a href="http://holon.gungfu.de/wiki/">HolonWiki</a> nicht mehr funktionierte, habe ich es jetzt wieder zum Laufen bekommen. War eine PHP-Einstellungssache.

Daher &#8211; zur Erinnerung &#8211; der Link dorthin: <a href="http://holon.gungfu.de/wiki/"><strong>http://holon.gungfu.de/wiki/</strong></a>]]></content:encoded>
			<wfw:commentRss>http://blog.gungfu.de/archives/2012/01/18/wieder-online-holonwiki/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Neues Tool in meinem Web-Stack: GNU Screen</title>
		<link>http://blog.gungfu.de/archives/2012/01/09/neues-tool-in-meinem-web-stack-gnu-screen/</link>
		<comments>http://blog.gungfu.de/archives/2012/01/09/neues-tool-in-meinem-web-stack-gnu-screen/#comments</comments>
		<pubDate>Mon, 09 Jan 2012 19:25:34 +0000</pubDate>
		<dc:creator>Steffen</dc:creator>
				<category><![CDATA[Unsortiertes]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[fastcgi]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jetty]]></category>
		<category><![CDATA[job control]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[noir]]></category>
		<category><![CDATA[screen]]></category>
		<category><![CDATA[Webentwicklung]]></category>

		<guid isPermaLink="false">http://blog.gungfu.de/?p=2512</guid>
		<description><![CDATA[Die Tage habe ich ein wenig mit der Webentwicklung in Clojure herumexperimentiert und war erstaunt, wie schnell ich eine lauffähige Webanwendung aufgesetzt hatte (dazu in einem separaten Eintrag). Begeistert von der einfachen Entwicklung habe ich mir gleich überlegt, wie ich eine solche Anwendung bei meinem Hoster deployen könnte. Da Clojure schlussendlich auf der JVM läuft [...]]]></description>
			<content:encoded><![CDATA[<p>Die Tage habe ich ein wenig mit der <a href="http://wiki.gungfu.de/Main/WebDevelopmentWithClojure"><strong>Webentwicklung in Clojure</strong></a> herumexperimentiert und war erstaunt, wie schnell ich eine lauffähige Webanwendung aufgesetzt hatte (dazu in einem separaten Eintrag).</p>

<p>Begeistert von der einfachen Entwicklung habe ich mir gleich überlegt, wie ich eine solche Anwendung bei meinem <a href="https://www.hostsharing.net/">Hoster</a> deployen könnte.</p>

<p>Da <a href="http://clojure.org/">Clojure</a> schlussendlich auf der <a href="http://en.wikipedia.org/wiki/Java_virtual_machine">JVM</a> läuft ging es darum herauszufinden, wie ich eine Java-Anwendung bei meinem Hoster (und wahrscheinlich <i>hinter</i> einem Apache-Webserver) ansprechen könnte.</p>

<p><i>Kurz</i> &#8211; um möglichst schnell ein Ergebnis zu haben &#8211; dachte ich an <a href="http://en.wikipedia.org/wiki/Common_Gateway_Interface">CGI</a>. Da reines CGI (wegen der Startzeit der JVM) aber schon eher über kurz als über lang keine tragfähige Lösung sein würde, habe ich mich <a href="http://en.wikipedia.org/wiki/FastCGI">FastCGI</a> zugewandt.</p>

<p>Ich kann mich erinnern, wie ich damals <a href="https://www.djangoproject.com/">Django</a> (ein Web-Framework für Python) mit <a class="wikiLink" href="http://wiki.gungfu.de/Main/FastCGI">FastCGI</a> eingerichtet habe: Hat nicht sofort funktioniert. Speziell im Zusammenspiel mit <a href="http://httpd.apache.org/docs/current/mod/mod_rewrite.html">mod_rewrite</a> hatte ich mit <a href="https://docs.djangoproject.com/en/dev/howto/deployment/fastcgi/">django.fcgi</a> meine Probleme. Inzwischen läuft&#8217;s. Und das tut&#8217;s recht gut.</p>

<p>Äußerst praktisch an der <a class="wikiLink" href="http://wiki.gungfu.de/Main/FastCGI">FastCGI</a>-Lösung ist (neben der Tatsache, dass es sich entgegen einer CGI-Lösung um einen langlaufenden Prozess handelt und so die Startzeiten großteils entfallen), dass Apache automatisch neue <a class="wikiLink" href="http://wiki.gungfu.de/Main/FastCGI">FastCGI</a>-Threads startet, wenn mehr Anfragen kommen. D.h. auch, dass bei einer Anfrage automatisch ein Django-Server gestartet wird, falls überhaupt keiner mehr läuft (weil der letzte beispielsweise wegen einer Exception ausgefallen ist). Also: es gibt automatisch immer einen Serverprozess, der eine ankommende Anfrage bearbeitet.</p>

<p>Das von mir eingesezte Clojure-Framework für die Webentwicklung (<a href="http://www.webnoir.org/"><strong>Noir</strong></a>) startet eine <a href="http://www.eclipse.org/jetty/"><strong>Jetty</strong></a>-Instanz (ein Webserver und <a href="http://docs.oracle.com/javaee/5/api/javax/servlet/package-summary.html">javax.servlet</a>-Container) &#8211; daher war eine Proxy-Lösung (Apache leitet bestimmte Anfragen an die Jetty-Instanz weiter) noch naheliegender als eine <a class="wikiLink" href="http://wiki.gungfu.de/Main/FastCGI">FastCGI</a>-basierte Lösung.</p>

<p>Da die Jetty-Instanz sowieso schon am Laufen ist, war nur noch die Frage zu klären, wie ich diese Instanz bei meinem Hoster am Laufen <i>halten</i> kann. Denn normalerweise werden beim Ausloggen Prozesse geschlossen, die über den Shell-Zugang gestartet wurden.</p>

<p>Aus meinen Studienzeiten kannte ich noch <a href="http://www.thegeekstuff.com/2010/05/unix-background-job/"><code>Ctrl-Z + bg</code></a>, was mir hier nicht die richtige Lösung schien. Nach kurzer Recherche bin ich auf eine meiner Meinung nach einigermaßen saubere Lösung gestoßen: <a href="http://www.nixtutor.com/linux/introduction-to-gnu-screen/"><strong>GNU Screen</strong></a>. Davon hatte ich schon gehört &#8211; mir war aber nicht klar, wie praktisch dieses Werkzeug sein kann. (Ein Vergleich der verschiedenen Möglichkeiten der Jobkontrolle: <a href="http://www.xaprb.com/blog/2008/08/01/how-to-leave-a-program-running-after-you-log-out/"><strong>How to leave a program running after you log out</strong></a>.) </p>

<p>Kurz: Man kann eine Screen-Session mit <code>screen -R -D</code> starten und dann ganz normal in der Shell arbeiten. Mit <code>Ctrl-a d</code> kann man die Session abhängen und in der &#8216;normalen&#8217; Shell arbeiten (oder sich ausloggen) &#8211; die in der Screen-Session gestarteten Anwendungen laufen aber weiter!<br />Beim nächsten Login kann man sich mit <code>screen -R -D</code> wieder an diese Session hängen.</p>

<p>Wenn man nun die Clojure-Web-Anwendung in so einer Session startet, läuft diese auch nach einem Logout weiter. Fehlermeldungen (Stacktraces), etc. kann man sich beim nächsten Einloggen und Anhängen an diese Session anschauen. Es geht nichts verloren.</p>

<p>Unpraktisch (aber bislang nicht problematisch) finde ich an dieser Lösung, dass der Jetty-Server nicht automatisch neu gestartet wird, wenn er mal abschmiert. Aber dafür könnte man einen Watcher schreiben &#8211; vielleicht gibt&#8217;s aber auch hierfür ein Werkzeug &#8211; oder vielleicht kann das der Apache (wie bei der <a class="wikiLink" href="http://wiki.gungfu.de/Main/FastCGI">FastCGI</a>-Lösung). Hat da jemand einen Tipp?</p>

<p>Screen kann noch viel mehr. Z.B. kann man verschiedene Sessions verwalten indem man Namen vergibt. Screen eignet sich auch für Anwendungsfälle, die scheinbar nichts mit dem hier beschriebenen zu tun haben: Pair Programming, Arbeiten mit mehreren Monitoren. Einfach mal in die <a href="http://linux.die.net/man/1/screen">MAN-Page zu Screen</a> schauen&#8230;</p>

<p>Nachdem die von Noir mitgebrachte Beispielanwendung läuft, gibt&#8217;s auch schon ein <em>erstes Projekt</em> meinerseits:<br /> Da die Vorschlagliste der &#8216;related posts&#8217; in der Denkzeit nicht befriedigend ist (hängt wohl mit dem Einsatz eines <a href="http://www.codehooligans.com/2008/04/18/versioning-your-blog-content/">Versionierungsplugins für WordPress</a> und der dadurch geänderten Datenbankstruktur zusammen), soll eine Anwendung entstehen, die eine sinnvolle Liste verwandter Blogeinträge zurückgibt. Naheliegenderweise wird das als <a href="http://wiki.gungfu.de/Main/REST">RESTful</a> <a href="http://wiki.gungfu.de/Main/WebServices">Web Service</a> implementiert.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.gungfu.de/archives/2012/01/09/neues-tool-in-meinem-web-stack-gnu-screen/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Neues Zitat: it&#8217;s not easy to make it simple</title>
		<link>http://blog.gungfu.de/archives/2011/12/30/neues-zitat-its-not-easy-to-make-it-simple/</link>
		<comments>http://blog.gungfu.de/archives/2011/12/30/neues-zitat-its-not-easy-to-make-it-simple/#comments</comments>
		<pubDate>Fri, 30 Dec 2011 19:05:34 +0000</pubDate>
		<dc:creator>Steffen</dc:creator>
				<category><![CDATA[Unsortiertes]]></category>
		<category><![CDATA[Simplicity]]></category>
		<category><![CDATA[zitate]]></category>

		<guid isPermaLink="false">http://blog.gungfu.de/?p=2502</guid>
		<description><![CDATA[All too often we do what’s easy, at the expense of what’s simple.Autor: Rich HickeyQuelle: http://www.infoq.com/presentations/Simple-Made-Easy Weitere Zitate gibt&#8217;s in der Zitatsammlung. Eine Liste der neuesten Zitate gibt es auch.]]></description>
			<content:encoded><![CDATA[<blockquote><p>All too often we do what’s easy, at the expense of what’s simple.</p></blockquote><cite>Autor: Rich Hickey</cite><br /><cite>Quelle: <a href="http://www.infoq.com/presentations/Simple-Made-Easy">http://www.infoq.com/presentations/Simple-Made-Easy</a></cite>

<p>Weitere Zitate gibt&#8217;s in der <a href="http://www.gungfu.de/zitate/">Zitatsammlung</a>. Eine Liste der <a href="http://www.gungfu.de/zitate/#latestQuotesH">neuesten Zitate</a> gibt es auch.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.gungfu.de/archives/2011/12/30/neues-zitat-its-not-easy-to-make-it-simple/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Aikido Yoshinkan in Wolframs-Eschenbach: Anfängerkurs ab Januar 2012!</title>
		<link>http://blog.gungfu.de/archives/2011/12/29/aikido-yoshinkan-in-wolframs-eschenbach-anfangerkurs-ab-januar-2012/</link>
		<comments>http://blog.gungfu.de/archives/2011/12/29/aikido-yoshinkan-in-wolframs-eschenbach-anfangerkurs-ab-januar-2012/#comments</comments>
		<pubDate>Thu, 29 Dec 2011 18:54:59 +0000</pubDate>
		<dc:creator>Steffen</dc:creator>
				<category><![CDATA[Unsortiertes]]></category>
		<category><![CDATA[Aikido]]></category>
		<category><![CDATA[dojo-sochin]]></category>

		<guid isPermaLink="false">http://blog.gungfu.de/?p=2479</guid>
		<description><![CDATA[Nachdem ich vor einiger Zeit mein Aikido-Training in Nürnberg aufgeben musste, habe ich im Oktober letzten Jahres mit Karate gleich bei mir um die Ecke (in Wolframs-Eschenbach) begonnen. Vor Kurzem hat sich die unerwartete Möglichkeit geboten, nach dem Karate-Training eine Stunde Aikido zu trainieren (bzw. zu lehren). Bislang nahmen an diesem Aikido-Training meine Karate-Freunde teil. [...]]]></description>
			<content:encoded><![CDATA[<a href="http://blog.gungfu.de/archives/2004/05/29/g04-one-thought/"><img src="/i/gi2004_shumatsu.jpg" class="imgR" alt="shumatsu dosa in Spanien"/></a>

<p>Nachdem ich vor einiger Zeit mein Aikido-Training in Nürnberg aufgeben musste, habe ich im Oktober letzten Jahres mit <a href="http://www.dojo-sochin.de/">Karate gleich bei mir um die Ecke (in Wolframs-Eschenbach)</a> begonnen.</p>

<p>Vor Kurzem hat sich die unerwartete Möglichkeit geboten, nach dem Karate-Training eine Stunde Aikido zu trainieren (bzw. zu lehren). Bislang nahmen an diesem Aikido-Training meine Karate-Freunde teil.</p>

<img class="imgR" src="http://www.gungfu.de/facts/wp-content/uploads/2006/04/aikido_josef_steffen.jpg" alt="Josef wirft Steffen in seiner Dan-Prüfung."/>

<p>Aber jetzt ist es so weit: <em>Ab 17. Januar 2012 gibt es einen Anfängerkurs (immer Dienstags)</em> im <a href="http://www.gungfu.de/aikido/">Aikido</a> (Stilrichtung: <a href="http://wiki.gungfu.de/Main/AikidoYoshinkan">Yoshinkan</a>).</p>

<p>Weitere Infos und Kontaktdaten gibt&#8217;s auf der Vereinshomepage: <a href="http://www.dojo-sochin.de/">dojo-sochin.de</a></p>



]]></content:encoded>
			<wfw:commentRss>http://blog.gungfu.de/archives/2011/12/29/aikido-yoshinkan-in-wolframs-eschenbach-anfangerkurs-ab-januar-2012/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Frohe Weihnachten, schonmal!</title>
		<link>http://blog.gungfu.de/archives/2011/12/23/frohe-weihnachten/</link>
		<comments>http://blog.gungfu.de/archives/2011/12/23/frohe-weihnachten/#comments</comments>
		<pubDate>Fri, 23 Dec 2011 08:39:00 +0000</pubDate>
		<dc:creator>Steffen</dc:creator>
				<category><![CDATA[Unsortiertes]]></category>
		<category><![CDATA[comic]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[xkcd]]></category>

		<guid isPermaLink="false">http://blog.gungfu.de/?p=2465</guid>
		<description><![CDATA[Dieses Jahr wünsche ich mal ein Frohes Fest &#8211; und zwar mit folgendem Comic von XKCD:]]></description>
			<content:encoded><![CDATA[<p>Dieses Jahr wünsche ich mal ein Frohes Fest &#8211; und zwar mit folgendem Comic von <a href="http://xkcd.com/">XKCD</a>:</p>

<a href="http://xkcd.com/835/"><img src="http://imgs.xkcd.com/comics/tree.png" alt="Christmas Heap" /></a>]]></content:encoded>
			<wfw:commentRss>http://blog.gungfu.de/archives/2011/12/23/frohe-weihnachten/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Verbesserung der Buildqualität (in TeamSystem) mit Hilfe eines zweiten Versionierungssystems (Mercurial, Git, Subversion, &#8230;)</title>
		<link>http://blog.gungfu.de/archives/2011/12/18/verbesserung-der-buildqualitat-in-teamsystem-mit-hilfe-eines-zweiten-versionierungssystems-mercurial-git-subversion/</link>
		<comments>http://blog.gungfu.de/archives/2011/12/18/verbesserung-der-buildqualitat-in-teamsystem-mit-hilfe-eines-zweiten-versionierungssystems-mercurial-git-subversion/#comments</comments>
		<pubDate>Sun, 18 Dec 2011 19:46:16 +0000</pubDate>
		<dc:creator>Steffen</dc:creator>
				<category><![CDATA[Unsortiertes]]></category>
		<category><![CDATA[Continuous Integration]]></category>
		<category><![CDATA[DCVS]]></category>
		<category><![CDATA[Gated Checkin]]></category>
		<category><![CDATA[mercurial]]></category>
		<category><![CDATA[TeamSystem]]></category>
		<category><![CDATA[VersionControl]]></category>

		<guid isPermaLink="false">http://blog.gungfu.de/?p=2444</guid>
		<description><![CDATA[Situationsbeschreibung Der Projektcode wird im TeamSystem verwaltet. Es gibt eine Checkin Policy, die besagt, dass vor einem Checkin ein RELEASE-Build gebaut werden muss. Da die Rule-Sets im RELEASE-Build strenger als im DEBUG-Build sind (Warnings in DEBUG sind ERRORS im RELEASE und führen zu einem Abbruch des Builds) &#8211; soll so eine gewisse Codequaltität beim Einchecken [...]]]></description>
			<content:encoded><![CDATA[<a href="http://de.wikipedia.org/wiki/Itsukushima-Schrein"><img src="http://blog.gungfu.de/wp-content/uploads/2011/12/Itsukushima_torii.jpg" alt="Torii Itsukushima" title="Itsukushima_torii" width="283" height="240" class="alignright size-full wp-image-2445 imgR" /></a>


<h3>Situationsbeschreibung</h3>

<ul>
<li>Der Projektcode wird im <a class="wikiLink" href="http://wiki.gungfu.de/Main/TeamSystem">TeamSystem</a> verwaltet.</li>
<li>Es gibt eine Checkin Policy, die besagt, dass vor einem Checkin ein RELEASE-Build gebaut werden muss.

<ul><li>Da die Rule-Sets im RELEASE-Build strenger als im DEBUG-Build sind (Warnings in DEBUG sind ERRORS im RELEASE und führen zu einem Abbruch des Builds) &#8211; soll so eine gewisse Codequaltität beim Einchecken sichergestellt und erzwungen werden.</li></ul>

</li>
</ul>

<h3>Problembeschreibung</h3>

<ul><li>Es reicht, wenn man ein RELEASE-Build irgendeiner Solution baut.
<ul><li>Insbesondere wird die <a class="wikiLink" href="http://wiki.gungfu.de/Main/UnitTest">UnitTest</a>-Solution selten auf Buildfähigkeit hin kontrolliert.</li></ul>
</li>
<li>Nach dem erfolgreichen RELEASE-Build werden nicht alle Dateien eingecheckt (weil man noch &#8220;mitten drin&#8221; in der Entwicklung ist).</li>
</ul>

<h3>Lösungsansätze</h3>

<ul><li>Mittels <strong><a href="http://wiki.gungfu.de/Main/GatedCheckin">Gated Checkins</a></strong> können beide Probleme in Angriff genommen und gelöst werden.</li>
<li>was aber, wenn (noch) kein Gated Checkin aufgesetzt ist oder sich das Team gegen einen Gated Checkin entschieden hat (weil es den Entwicklungsfluß (<em>zunächst</em>) verzögert)? Zumindest für <i>eigene</i> Änderungen kann man mit einem zweiten, lokal eingesetzten Versionierungssystem einigermaßen sicherstellen, dass man den Build auf einer anderen Entwicklermaschine nicht stört. Das Problem mit der <a class="wikiLink" href="http://wiki.gungfu.de/Main/UnitTest">UnitTest</a>-Solution lässt sich hier aber nur durch Disziplin in den Griff bekommen (aber Disziplin wäre <i>oft</i> eine Lösung für die unterschiedlichsten Probleme).</li>
</ul>


<h4>Mein Vorschlag: Ein zweites Versoinierungssystem zur Verbesserung der Buildqualität</h4>

<p>Meine Lösung besteht zur Zeit darin, die Sourcen lokal nochmal zu versionieren. Bei mir kommt <a href="http://wiki.gungfu.de/Main/Mercurial">Mercurial</a> zum Einsatz &#8211; prinzipiell eignen sich alle leichtgewichtigen Versionierungssysteme.</p>

<p class="exkurs" style="font-size:75%">Bei Subversion habe ich schlechte Erfahrungen mit den überall im Dateisystem rumhängenden .svn- Verzeichnissen gemacht: Das Zusammenspiel mit TFS wird dadurch nämlich nicht einfacher. Schnell ist so ein Verzeichnis mal aus versehen gelöscht. Auch ein Wechsel in einen zweiten TFS-Workspace ist mit den vielen .svn-Verzeichnissen nicht durch Kopieren möglich.<p>

<p>Durch die lokale Versionierung, relativ häufiges Commiten in das lokale System und die Möglichkeit lokale Commits vor dem eigentlichen Commit in das <a class="wikiLink" href="http://wiki.gungfu.de/Main/TeamSystem">TeamSystem</a> nochmal aufzuräumen (durch Umstellen oder Löschen von Changesets, in Mercurial beispielsweise mittels der <a href="http://mercurial.selenic.com/wiki/HisteditExtension">Histedit-Extension</a>, <a href="http://mercurial.selenic.com/wiki/RebaseExtension">Rebasing</a> oder <a href="http://mercurial.selenic.com/wiki/Strip">Stripping</a>) &#8211; entsteht <strong>die Möglichkeit einen lokalen Sourcestand zusammenzustellen</strong>, der nach einem erfolgreichen lokalen RELEASE-Build <strong>genau so</strong> auch in das <a class="wikiLink" href="http://wiki.gungfu.de/Main/TeamSystem">TeamSystem</a> eingecheckt wird.</p>

<p>Das heißt konkret, dass es keine Dateien gibt, die zwar lokal mitgebaut (im durch die Checkin-Policy verlangten RELEASE-Build) aber nicht eingecheckt werden (weil man noch &#8216;mitten drin&#8217; ist).</p>

<p><em>Nochmal: Alles, was lokal gebaut wurde (wenn es gebaut werden konnte) wird auch ins <a class="wikiLink" href="http://wiki.gungfu.de/Main/TeamSystem">TeamSystem</a> eingepflegt.</em></p>

<p>Weil die zusätzliche lokale Versionierung noch weitere Vorteile bietet (möglicherweise auch im Zusammenspiel mit <a href="http://wiki.gungfu.de/Main/GatedCheckin">Gated Checkins</a>), bin ich inzwischen ein großer Fan von diesem Vorgehen. In zukünftigen Einträgen werde ich dieses Vorgehen weiter beleuchten.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gungfu.de/archives/2011/12/18/verbesserung-der-buildqualitat-in-teamsystem-mit-hilfe-eines-zweiten-versionierungssystems-mercurial-git-subversion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>minimal?</title>
		<link>http://blog.gungfu.de/archives/2011/12/04/minimal/</link>
		<comments>http://blog.gungfu.de/archives/2011/12/04/minimal/#comments</comments>
		<pubDate>Sun, 04 Dec 2011 19:19:39 +0000</pubDate>
		<dc:creator>Steffen</dc:creator>
				<category><![CDATA[Unsortiertes]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[Simplicity]]></category>
		<category><![CDATA[Softwareentwicklung]]></category>

		<guid isPermaLink="false">http://blog.gungfu.de/?p=2434</guid>
		<description><![CDATA[Einer meiner Profs an der Uni hatte in der Vorlesung &#8220;Theoretische Informatik I&#8221; eine &#8211; wie ich damals fand &#8211; Macke, die sich dadurch äußerte, dass er unter jede konstruierte Turing-Maschine oder Automaten eine ziemlich kurz geratene Frage schrieb: minimal? Damals habe ich nicht erkannt, wie wichtig diese Frage (und die Antwort darauf) ist. Inzwischen [...]]]></description>
			<content:encoded><![CDATA[<p>Einer meiner Profs an der Uni hatte in der Vorlesung &#8220;Theoretische Informatik I&#8221; eine &#8211; wie ich damals fand &#8211; Macke, die sich dadurch äußerte, dass er unter jede konstruierte Turing-Maschine oder Automaten eine ziemlich kurz geratene Frage schrieb: <strong>minimal?</strong></p>

<p>Damals habe ich nicht erkannt, wie wichtig diese Frage (und die Antwort darauf) ist. Inzwischen ist mir klar, dass &#8211; vielleicht nicht Minimalität, sondern <strong>Einfachheit</strong> &#8211; den Unterschied zwischen einer guten und einer schlechten Lösung &#8211; den Unterschied zwischen viel und wenig nachgedacht macht.</p>

<p>Abgesehen davon, dass die Minimalität nicht immer bewiesen werden kann (wenn ich mich recht erinnere). So ist <em>Einfachheit</em> doch eine objektive Größe: <em>Der Grad der Verwicklungen/Verstrickungen/Abhängigkeiten mit weiteren Konzepten.</em><br />
Konkretes Beispiel: Die Abhängigkeiten eines Programmmoduls: je weniger Abhängigkeiten, desto einfacher ist es.</p>

<p>Oft genug wird man vor eine Lösung gestellt, die durch offensichtliche Kompliziertheit (ein hoher Grad an Verwicklungen/Abhängigkeiten) zunächst besticht. Inzwischen stelle ich mir insgeheim immer mehr die Fragen: <em>minimal? einfach?</em></p>

<p class="exkurs" style="font-size:75%">Der Unterschied zwischen <em>Kompliziertheit</em> und <em>Komplexität</em> ist übrigens meiner Meinung nach: ersteres ist künstlich, auf das Wie zurückführbar. Komplexität ist dem Problem (bzw. dessen Lösung) innewohnend und kann nicht entfernt werden. Mit Komplexität muss umgegangen, Kompliziertheit muss vermieden werden.<br />
Oder kurz: <quote>Komplexität ist eine Eigenschaft des Problems &#8211; Kompliziertheit ist eine Eigenschaft der Lösung.</quote></p>

<p>Ist es wirklich nötig, dass diese Lösung &#8211; die zugegebenermaßen funktioniert &#8211; so kompliziert ist? Meist ist so eine Lösung zwar leicht zu realisieren (zwar mit vielen Klassen, Interfaces, Wiederholungen und Tipparbeit oder Codegenerierern &#8211; aber ohne viel notwendigen Grips), aber sie ist nicht einfach, sondern eher zwei-, drei- oder mehrfach. <br />
Über den Unterschied zwischen einfach und leicht (simple and easy) gab&#8217;s vor Kurzem eine recht aufschlussreiche und offensichtlich sehr anregende Diskussion in der Clojure-Gemeinde, angestoßen durch einen <a href="http://www.infoq.com/presentations/Simple-Made-Easy">Konverenzvortrag</a> von <a href="http://wiki.gungfu.de/Main/RichHickey">Rich Hickey</a>.</p>

<p>Ohne weiteres Nachdenken ist die Frage nach Einfachheit tatsächlich nur schwer zu beantworten. Man &#8211; zumindest ich &#8211; läuft Gefahr eine alternative Lösung zu erarbeiten, die anders aussieht, anders funktioniert und in dieser Andersartigkeit in Wirklichkeit dieselbe Komplexität &#8216;versteckt&#8217;.</p>

<p>Bei Softwareentwicklern geht zusätzlich noch die Seuche des <i>Komplizitismus</i> um: Je komplizierter eine Lösung ist, die da entwickelt wurde &#8211; je länger ein anderer benötigt, diese Lösung zu verstehen, desto fortgeschrittener muss derjenige sein, der die Lösung entwickelt hat. <!--Wie oft hat man schon gehört: "Besser nichts ändern, es könnte was kaputt gehen wenn man was übersieht bzw. wenn man eine (implizite) Abhängigkeit nicht bedenkt."--><br />
Das ist nicht nur falsch! Dieses Denken ist in einem Team sogar gefährlich (Stichwort: Wartbarkeit im Urlaubsfall).</p>

<blockquote><p>I have made this letter longer than usual, because I lack the time to make it short.</p></blockquote><cite>Blaise Pascal</cite>


<p>Vielleicht entwickelt man ein Gespür für unnötige Kompliziertheit und simple Lösungen. Wenn man sich der Problematik bewusst ist&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gungfu.de/archives/2011/12/04/minimal/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>John McCarthy ist tot</title>
		<link>http://blog.gungfu.de/archives/2011/10/28/john-mccarthy-ist-tot/</link>
		<comments>http://blog.gungfu.de/archives/2011/10/28/john-mccarthy-ist-tot/#comments</comments>
		<pubDate>Fri, 28 Oct 2011 09:30:48 +0000</pubDate>
		<dc:creator>Steffen</dc:creator>
				<category><![CDATA[Unsortiertes]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[Lisp]]></category>

		<guid isPermaLink="false">http://blog.gungfu.de/?p=2427</guid>
		<description><![CDATA[Wie ich gerade eben feststellen musste, ist John McCarthy, der Entdecker von Lisp und Vater der AI am 23. Oktober gestorben. John McCarthy, in Memoriam (Remembering (John (McCarthy (1927 &#8211; 2011)))) Im Denkzeitwiki sammle ich schon seit einiger Zeit Artikel und Infos von und zu JohnMcCarthy]]></description>
			<content:encoded><![CDATA[<img src='http://wiki.gungfu.de/uploads/Main/john_mccarthy.jpg' class="imgR" alt='John McCarthy' />

<p>Wie ich gerade eben feststellen musste, ist John <a class="wikiLink" href="http://wiki.gungfu.de/Main/McCarthy">McCarthy</a>, der Entdecker von Lisp und Vater der AI am 23. Oktober gestorben.</p>

<ul>
	<li><a href="http://drdobbs.com/architecture-and-design/231901597">John McCarthy, in Memoriam</a></li>
	<li><a href="http://spectrum.ieee.org/tech-talk/robotics/artificial-intelligence/remembering-john-mccarthy-1927-2011">(Remembering (John (McCarthy (1927 &#8211; 2011))))</a></li>
</ul>

<p>Im Denkzeitwiki sammle ich schon seit einiger Zeit Artikel und Infos von und zu <a href="http://wiki.gungfu.de/Main/JohnMcCarthy">JohnMcCarthy</a></p>



]]></content:encoded>
			<wfw:commentRss>http://blog.gungfu.de/archives/2011/10/28/john-mccarthy-ist-tot/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>3 Einführungen zu Clojure</title>
		<link>http://blog.gungfu.de/archives/2011/09/14/3-einfuhrungen-zu-clojure/</link>
		<comments>http://blog.gungfu.de/archives/2011/09/14/3-einfuhrungen-zu-clojure/#comments</comments>
		<pubDate>Wed, 14 Sep 2011 19:22:15 +0000</pubDate>
		<dc:creator>Steffen</dc:creator>
				<category><![CDATA[Unsortiertes]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[Links]]></category>

		<guid isPermaLink="false">http://blog.gungfu.de/?p=2409</guid>
		<description><![CDATA[Für einen Kollegen habe ich eine kurze Liste von Einführungen in die Programmiersprache Clojure zusammengestellt. Die möchte ich hier kurz weitergeben. Ich denke, die drei Einführungen sprechen unterschiedliche Geschmäcker an &#8211; könnte also für jeden was dabei sein: http://www.infoq.com/presentations/Clojure-Towards-The-Essence-Of-ProgrammingPräsentation mit Folien und MP3 zum nebenbei hören. Gefällt mir ganz gut &#8211; bin mir aber nicht [...]]]></description>
			<content:encoded><![CDATA[<img alt="clojures logo" src="http://wiki.gungfu.de/uploads/Main/clojure-icon.gif" title="clojures logo" class="alignright" width="100" height="100" />

<p>Für einen Kollegen habe ich eine kurze Liste von Einführungen in die Programmiersprache Clojure zusammengestellt. Die möchte ich hier kurz weitergeben. Ich denke, die drei Einführungen sprechen unterschiedliche Geschmäcker an &#8211; könnte also für jeden was dabei sein:</p>

<ul>
	<li><a href="http://www.infoq.com/presentations/Clojure-Towards-The-Essence-Of-Programming">http://www.infoq.com/presentations/Clojure-Towards-The-Essence-Of-Programming</a><br />Präsentation mit Folien und MP3 zum nebenbei hören. Gefällt mir ganz gut &#8211; bin mir aber nicht sicher, ob&#8217;s für den Einstieg zu knackig ist.</li>
	<li><a href="http://java.ociweb.com/mark/clojure/article.html">http://java.ociweb.com/mark/clojure/article.html</a><br />Ist eine sehr gute, umfassende Einführung.</li>
	<li><a href="http://www.lisperati.com/clojure-spels/casting.html">http://www.lisperati.com/clojure-spels/casting.html</a><br />Auch gut und gut gemacht.</li>
</ul>

<p>Weitere Links &#8211; z.B. zu im Browser laufende <a href="http://wiki.gungfu.de/Main/ReadEvalPrint">REPLs</a>, Sammlungen von Programmieraufgaben oder verschiedene Videos, etc. &#8211; gibt&#8217;s im Denkzeitwiki: <a href="http://wiki.gungfu.de/Main/GettingStartedWithClojure">GettingStartedWithClojure</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gungfu.de/archives/2011/09/14/3-einfuhrungen-zu-clojure/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Disable exceptions in Visual Studio programmatically</title>
		<link>http://blog.gungfu.de/archives/2011/08/27/disable-exceptions-in-visual-studio-programamtically/</link>
		<comments>http://blog.gungfu.de/archives/2011/08/27/disable-exceptions-in-visual-studio-programamtically/#comments</comments>
		<pubDate>Sat, 27 Aug 2011 18:28:09 +0000</pubDate>
		<dc:creator>Steffen</dc:creator>
				<category><![CDATA[Unsortiertes]]></category>
		<category><![CDATA[F#]]></category>
		<category><![CDATA[gist]]></category>
		<category><![CDATA[snippet]]></category>
		<category><![CDATA[VisualStudio]]></category>

		<guid isPermaLink="false">http://blog.gungfu.de/?p=2397</guid>
		<description><![CDATA[It only recently occurred to me that learning some F# would be rather well timed (after having hacked quite some clojure recently). Searching for stuff I could get my feet wet with, I realized the possibilities for automating VisualStudio by using F# Interactive (a F# console that can also be used inside Visual Studio &#8211; [...]]]></description>
			<content:encoded><![CDATA[<p>It only recently occurred to me that learning some <a href="http://wiki.gungfu.de/Main/FSharp">F#</a> would be rather well timed (after having hacked quite some <a href="http://wiki.gungfu.de/Main/Clojure">clojure</a> recently).</p>

<p>Searching for stuff I could get my feet wet with, I realized the possibilities for automating <a class="wikiLink" href="http://wiki.gungfu.de/Main/VisualStudio">VisualStudio</a> by using <a href="http://chrismarinos.com/5-reasons-to-use-f-interactive-in-visual-studio-2010/">F# Interactive</a> (a F# console that can <em>also</em> be used inside Visual Studio &#8211; the other way would be to call <strong><code>fsi</code></strong> in a VS 2010 cmd-box).</p>

<p>One thing that really bugs me when debugging in Visual Studio with the option &#8220;break on exceptions&#8221; enabled was that the debugger will halt on lots of exceptions which I am not interested in. It&#8217;s possible to exclude those uninteresting exceptions in the exceptions-dialog (Ctr + Alt + e) but those settings cannot be saved and will be lost when &#8220;break on exceptions&#8221; will be disabled and re-enabled some other time.</p>

<p>So my first F#-script will disable exceptions in Visual Studio <strong>programmatically</strong>.</p>

<script src="https://gist.github.com/1175654.js"> </script>]]></content:encoded>
			<wfw:commentRss>http://blog.gungfu.de/archives/2011/08/27/disable-exceptions-in-visual-studio-programamtically/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>M-C-% /la_[0-9] RET /la_\,(+ 2 \#) RET</title>
		<link>http://blog.gungfu.de/archives/2011/07/23/m-c-la_0-9-ret-la_-2-ret/</link>
		<comments>http://blog.gungfu.de/archives/2011/07/23/m-c-la_0-9-ret-la_-2-ret/#comments</comments>
		<pubDate>Sat, 23 Jul 2011 18:34:03 +0000</pubDate>
		<dc:creator>Steffen</dc:creator>
				<category><![CDATA[Unsortiertes]]></category>
		<category><![CDATA[emacs]]></category>
		<category><![CDATA[emacs lisp]]></category>
		<category><![CDATA[RegEx]]></category>
		<category><![CDATA[thermonuklear]]></category>

		<guid isPermaLink="false">http://blog.gungfu.de/?p=2302</guid>
		<description><![CDATA[Was aussieht wie ein Kraftausdruck aus einem Manga, ist der Einstieg in eine Welt der turingvollständigen (ich weiß, ich weiß) Textersetzungen (in Emacs). Die Aufgabenstellung Ich wollte in einem Dokument an verschiedenen Stellen einen größeren Textblock einfügen. An jeder Stelle muss der eingefügte Text ein wenig abgeändert werden, d.h. er ist variabel und zwar in [...]]]></description>
			<content:encoded><![CDATA[<img src="http://blog.gungfu.de/wp-content/uploads/2011/05/speechbubble_emacs_regrepl.png" alt="" title="speechbubble_emacs_regrepl" width="345" height="60" class="alignright size-full wp-image-2337 imgR" />

<p>Was aussieht wie ein Kraftausdruck aus einem Manga, ist der Einstieg in eine Welt der <a href="http://de.wikipedia.org/wiki/Turing-Vollständigkeit">turingvollständigen</a> (ich weiß, ich weiß) Textersetzungen (in <a href="http://wiki.gungfu.de/Main/Emacs">Emacs</a>).</p>

<h2>Die Aufgabenstellung</h2>

<p>Ich wollte in einem Dokument an verschiedenen Stellen einen größeren Textblock einfügen. An jeder Stelle muss der eingefügte Text ein wenig abgeändert werden, d.h. er ist variabel und zwar in einer Zahl, die im Endeffekt für eine Indizierung hochgezählt werden musste.</p>

<h2>verschiedene Lösungsmöglichkeiten</h2>

<p>Zunächst dachte ich an <a href="http://www.emacswiki.org/emacs/CategoryTemplates">Texttemplates</a> ala <a href="http://www.emacswiki.org/emacs/Yasnippet">Yasnippet</a>. Da hätte ich dann eine Schabone definiert und das Hochzählen quasi sebst (manuell) erledigt. Allerdings stört mich an allen Texttemplate-Lösungen, die ich mir bisher angeschaut habe immer, dass es relativ umständlich ist, Schablonen zu definieren. Ich suche sowas wie eine ad-hoc-Eingabemögichkeit, habe sie aber noch nicht gefunden. Wahrscheinlich gibt es keine andere Möglichkeit als ein wenig <a class="wikiLink" href="http://wiki.gungfu.de/Main/EmacsLisp">EmacsLisp</a> in *scratch* zusammenzuschreiben.</p>

<p>Auf er Suche nach einer kürzeren Lösung habe ich noch kurz an <a href="http://www.emacswiki.org/emacs/AbbrevMode">Abbrev</a> gedacht, bin aber zum Schluß gekommen, dass ich am Ende noch Nacharbeit leisten müsste (nämlich den variablen Teil anpassen). Daher schieden auch die Abkürzungen für mich aus.</p>

<p>Schließlich habe ich die Aufgabe gelöst, indem ich den Textblock händisch an die Stellen kopiert habe, wo er hin sollte. Für den variablen Teil habe ich eine für mich neue Emacs-Technik eingesetzt: Suchen-und-Ersetzen mit regulären Ausdrücken (bis hierhin nichts Neues) unter Verwendung von <a class="wikiLink" href="http://wiki.gungfu.de/Main/EmacsLisp">EmacsLisp</a> Ausdrücken (neu!).</p>

<p>Die Eingabe <kbd>M-C-% /la_[0-9] RET /la_\,(+ 2 \#) RET</kbd> erledigt nämlich folgendes: Die Vorkommen des <a class="wikiLink" href="http://wiki.gungfu.de/Main/RegEx">RegEx</a> <code>/la_[0-9]</code> werden ersetzt mit <code>/la_\,(+ 2 \#)</code>, wobei <code>\,</code> einen <a class="wikiLink" href="http://wiki.gungfu.de/Main/EmacsLisp">EmacsLisp</a>-Ausdruck einläutet.</p>

<p>Genauer: Die Ersetzung findet Zeichenfolgen <code>/la_</code> mit einer angehängten Ziffer und ersetzt sie mit der Zeichenfolge <code>/la_</code> und der Anzahl der bisherigen Ersetzungen + 2.</p>

<p>Die Anzahl der bisherigen Ersetzungen startet bei 0. Da ich die Indizierung mit 2 anfangen musste, habe ich einfach zwei hinzuaddiert: <code>(+ 2 \#)</code>.</p>

<p>Konkrete Beispiele für Ersetzungen sind daher:</p>

<pre><code>/la_2 -> /la_2
/la_2 -> /la_3
/la_2 -> /la_4
/la_2 -> /la_5</code></pre>

<p>Fertig.</p>

<p>Mit <a class="wikiLink" href="http://wiki.gungfu.de/Main/EmacsLisp">EmacsLisp</a>-Ausdrücken im Ersetzungsteil kann man aber noch mehr machen. Neben <code>\#</code> (Ersetzungszähler) gibt es weitere Kürzel zum Zugriff auf den zu ersetzenden Text oder Teile davon: <code>\1</code> liefert die erste <a href="http://www.regular-expressions.info/named.html">Capturing Group</a> als <i>Text</i>, <code>\2</code> die zweite, etc. <code>\#1</code> liefert die erste Gruppe als <i>Zahlenwert</i>, <code>\#2</code> die zweite. <code>\&#038;</code> liefert den gesamten String. Alle Kürzel sind im Emacs-Handbuch unter <a href="http://www.gnu.org/software/libtool/manual/emacs/Regexp-Replace.html">19.9.2 Regexp Replacement</a> beschrieben.</p>


<h2>Ein weiteres Beispiel mit neuer Aufgabenstellung</h2>

<p>Angenommen, man müsste die oben durchgeführte Indizierung korrigieren, weil der Offset sich geändert hat. D.h. im obigen Beispiel hätten eigentlich folgende Ersetzungen durchgeführt werden müssen:</p>

<pre><code>/la_2 -> /la_4
/la_2 -> /la_5
/la_2 -> /la_6
/la_2 -> /la_7</code></pre>

<p>Man könnte jetzt &#8211; das Dokument auf einen früheren Stand (überall <code>/la_2</code>) zurücksetzen und &#8211; die oben verwendete Ersetzungsvorschrift <code>M-C-% /la_[0-9] RET /la_\,(+ 2 \#) RET</code> in <code>M-C-% /la_[0-9] RET /la_\,(+ 4 \#) RET</code> abändern.<br />
Diese Ersetzung ist durch das <code>\#</code> aber <em>Reihenfolgeabhängig</em> &#8211; und man müsste an den frühern Stand kommen (ich kenne und kann da zwei Möglichkeiten ans Herz legen: Versionierungssystem, incomprehensible Undo). Es geht unter Verwendung des oben bereits beschriebenen <code>\#1</code> und einer Capturing Group auch anders:</p>

<pre><code>M-C-% /la_\([0-9]\) RET /la_\,(+ 2 \#1) RET</code></pre>

<p>Zunächst mag man sich vielleicht wundern, warum so viele Escapes im Suchausdruck <code>/la_\([0-9]\)</code> vorkommen &#8211; gewohnterweise würde man <code>/la_([0-9])</code> schreiben. Nun &#8211; Emacs ist primär ein <strike>Betriebssystem</strike> Texteditor und es wird davon ausgegangen, dass häufiger nach Text gesucht wird, der Zeichen wie ( oder ) enthält, als dass reguläre Ausdrücke z.B. Capturing Groups (eingefasst mit ( und )) in Suchanfragen verwendet werden. Daher hat das textliche Zeichen erstmal Vorrang &#8211; die Metazeichen des <a class="wikiLink" href="http://wiki.gungfu.de/Main/RegEx">RegEx</a> müssen mit Escapes kenntlich gemacht werden.</p>

<p>Auf den Inhalt der Capturing Group kann in der Ersetzung mit <code>\1</code>, etc. zugegriffen werden. Das liefert einen String. Wir brauch aber eine Zahl &#8211; und die liefert <code>\#1</code>. Und mit dieser Zahl kann man dann &#8211; wie im Beispiel &#8211; rechnen.</p>

<p>Statt &#8216;nur&#8217; zu rechnen, können im <a class="wikiLink" href="http://wiki.gungfu.de/Main/EmacsLisp">EmacsLisp</a>-Ausdruck auch komplexere Funktionen verwendet werden. Natürlich auch selbst definierte. Man könnte Ersetzungen abhängig von anderen Dateien &#8211; auf anderen Rechnern machen, Internetabfragen starten, usw. usv..</p>

<p><a href="http://blog.gungfu.de/archives/2011/05/04/neues-zitat-emacs-stephensons-thermonuclear-word-processor/">Thermonuklear!</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gungfu.de/archives/2011/07/23/m-c-la_0-9-ret-la_-2-ret/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Die zwei Seiten des Connectionpoolings</title>
		<link>http://blog.gungfu.de/archives/2011/06/27/die-zwei-seiten-des-connectionpoolings/</link>
		<comments>http://blog.gungfu.de/archives/2011/06/27/die-zwei-seiten-des-connectionpoolings/#comments</comments>
		<pubDate>Mon, 27 Jun 2011 20:23:56 +0000</pubDate>
		<dc:creator>Steffen</dc:creator>
				<category><![CDATA[Unsortiertes]]></category>
		<category><![CDATA[.Net]]></category>
		<category><![CDATA[connection]]></category>
		<category><![CDATA[Datenbank]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[server]]></category>

		<guid isPermaLink="false">http://blog.gungfu.de/?p=2349</guid>
		<description><![CDATA[Anlässlich einer Weiterbildungsmaßnahme kam neulich das Thema Connection-Pooling auf. Wieder eines der Themen, bei denen meist vereinfachend nur eine Seite der Medaille gesehen wird (die Vorzüge) ohne dabei die Situationen zu berücksichtigen, in denen Connection Pooling nicht die beste Lösung ist. Wenn ich eins gelernt habe, dann ist es, dass es immer (mindestens) zwei Seiten [...]]]></description>
			<content:encoded><![CDATA[<p>Anlässlich einer Weiterbildungsmaßnahme kam neulich das Thema Connection-Pooling auf. Wieder eines der Themen, bei denen meist vereinfachend nur eine Seite der Medaille gesehen wird (die Vorzüge) ohne dabei die Situationen zu berücksichtigen, in denen Connection Pooling nicht die beste Lösung ist.</p>

<p>Wenn ich eins gelernt habe, dann ist es, dass es <strong>immer</strong> (mindestens) zwei Seiten gibt. Und dass man immer zumindest davon lernen kann diese beiden Seiten anzuschauen bzw. sich überhaupt zu überlegen, was die zweite Seite sein könnte.</p>

<p>Daher&#8230;</p>


<h2>Was ist Connection-Pooling?</h2>

<p>Das Bereitstellen mehrerer physischer Datenbankverbindungen über eine Schnittstelle &#8211; wobei der Verwender der Schnittstelle nicht merkt, dass es verschiedene Connections sind und sich auch nicht um deren Verwaltung kümmern muss, nennt man Connection-Pooling.</p>

<p>Beim Schließen einer solcher logischen Connection wird die darunterliegende physische zum SQL-Server nicht geschlossen, sondern die (nicht wirklich) geschlossene Verbindung wird zurück in einen Pool von Connections gegeben. Wird anschließend eine Connection vom Pool angefordert, wird willkürlich eine physische Verbindung aus dem Pool zurückgegeben (deren logischer Status geschlossen ist).</p>


<h2>Warum wird Connection Pooling verwendet?</h2>

<p>Der Aufbau einer physischen Verbindung zum SQL-Server ist teuer. Zu jeder Connection speichert der Server Verwaltungsinformationen, die beim Verbindungsaufbau erstmal zusammengestellt werden müssen.</p>

<p>Andererseits ist das anwendungsseitige Halten einer Verbindung ebenfalls teuer: schließlich handelt es sich bei so einer Verbindung um eine endliche Resource (Sockets, Named Pipes).</p>


<h2>Mögichkeiten des Verbindungsaufbaus.</h2>

<p>Erstmal gibt es diese zwei Möglichkeiten mit Verbindungen umzugehen:</p>


<ul>
<li>Connection aufbauen und wieder schließen &#8211; d.h. beispielsweise zu Beginn eines Use-Cases wird eine physische Verbindung hergestellt und an dessen Ende geschlossen.<br />Resourcenschonend, aber dauert länger.</li>

<li>Connection für Lebenszeit der Anwendung halten.<br />Resourcenbindend, aber logischerweise sehr schnell.</li>
</ul>

<p>Das Connection Pooling ist eine dritte Möglichkeit, die die beiden vorgenannten zu einem quasi besseren zusammenführt:<br />
Eine logische Connection wird freigegeben und steht neuen Anfragen zur Verfügung, physisch bleibt sie immer bestehen.</p>

<p>Unter .Net werden Pools angelegt pro: Prozess, App-Domain, Connection-String.<br />
Wenn sich also der Connection-String ändert (z.B. andere Anmeldung am SQL-Server) dann wird ein neuer Pool erzeugt. Auf der anderen Seite wird auch ein neuer Pool erzeugt, wenn derselbe Connection-String in einem neuen Prozess verwendet wird.</p>

<p>Die Verwendung von Connection-Pools erzeugt auch Overhead, nämlich den Abgleich der Connection-Strings.</p>


<h2>Wann macht Connection-Pooling Sinn?</h2>

<p>Bei interaktionslastigen Desktop-Anwendungen (z.B. Win-Forms-Anwendungen) kann man Connections durchaus für die Lebenszeit der Anwendung halten. Das ist dann mit Sicherheit die schnellste Möglichkeit wiederholt auf die Datenbank zu kommen, weil der Overhead des Connectionstringabgleichens entfällt.</p>

<p>Erfolgt der Zugriff auf dieselbe Datenbank über mehrere Instanzen verteilt (sprich gleichzeitig per Multithreading), dann lohnt sich Pooling wegen dem schonenderen Umgang mit der Resource Connection &#8211; beispielsweise also bei Web-Anwendungen oder generell Client-Server-Anwendungen mit mehreren Anwendern.</p>

<p>So, ich denke, das waren beide Seiten der Medaille&#8230;</p>

<p>Nachtrag: Eine Sammlung von Links gibt&#8217;s natürlich im Denkzeitwiki: <a class="wikiLink" href="http://wiki.gungfu.de/Main/ConnectionPooling">ConnectionPooling</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.gungfu.de/archives/2011/06/27/die-zwei-seiten-des-connectionpoolings/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Automatisieren von InternetExplorer und ein bisschen HTML-Scraping mit Clojure (CLR)</title>
		<link>http://blog.gungfu.de/archives/2011/05/25/automatisieren-von-internetexplorer-und-ein-bisschen-html-scraping-mit-clojure-clr/</link>
		<comments>http://blog.gungfu.de/archives/2011/05/25/automatisieren-von-internetexplorer-und-ein-bisschen-html-scraping-mit-clojure-clr/#comments</comments>
		<pubDate>Wed, 25 May 2011 18:46:23 +0000</pubDate>
		<dc:creator>Steffen</dc:creator>
				<category><![CDATA[Unsortiertes]]></category>
		<category><![CDATA[.Net]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[clr]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[html-scraping]]></category>
		<category><![CDATA[interop]]></category>
		<category><![CDATA[RegEx]]></category>
		<category><![CDATA[snippet]]></category>

		<guid isPermaLink="false">http://blog.gungfu.de/?p=2246</guid>
		<description><![CDATA[Die letzten Tage wollte ich mit Clojure den Inhalt einer Internetseite auswerten. Erstmal habe ich den Quellcode der Seite im IE angesehen und kam zu dem Schuß, dass das, was ich da zu Gesicht bekam, prinzipiell parsebar ist &#8211; allerdings nicht mit einem XML-Parser und auch jeder HTML-Parser, der was auf sich hält, würde die [...]]]></description>
			<content:encoded><![CDATA[<img alt="" src="http://wiki.gungfu.de/uploads/Main/clojure-icon.gif" title="clojures logo" class="alignright" width="100" height="100" />

<p>Die letzten Tage wollte ich mit Clojure den Inhalt einer Internetseite auswerten. Erstmal habe ich den Quellcode der Seite im IE angesehen und kam zu dem Schuß, dass das, was ich da zu Gesicht bekam, prinzipiell parsebar ist &#8211; allerdings nicht mit einem XML-Parser und auch jeder HTML-Parser, der was auf sich hält, würde die Seite nicht verarbeiten. D.h. XPath scheidet aus. Schlußendlich bin ich &#8211; mal wieder &#8211; bei regulären Ausdrücken <a href="http://www.codinghorror.com/blog/2008/06/regular-expressions-now-you-have-two-problems.html">gelandet</a>:</p>

<div id="wpshdo_2" class="wp-synhighlighter-outer"><div id="wpshdt_2" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_2"></a><a id="wpshat_2" class="wp-synhighlighter-title" href="#codesyntax_2"  onClick="javascript:wpsh_toggleBlock(2)" title="Click to show/hide code block">Code block</a></td><td align="right"><a href="#codesyntax_2" onClick="javascript:wpsh_code(2)" title="Show code only"><img border="0" style="border: 0 none" src="http://blog.gungfu.de/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_2" onClick="javascript:wpsh_print(2)" title="Print code"><img border="0" style="border: 0 none" src="http://blog.gungfu.de/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://blog.gungfu.de/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://blog.gungfu.de/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_2" class="wp-synhighlighter-inner" style="display: block;"><pre class="clojure" style="font-family:monospace;"><span class="br0">&#40;</span><span class="kw1">def</span> pat #<span class="st0">&quot;(?s)&gt;Kommt&lt;/TD&gt;.*?&lt;TD class=.*?&gt;(.*?)&lt;/TD&gt;&quot;</span><span class="br0">&#41;</span></pre></div></div>

<p>Das nächste und unerwarteterweise größte Problem war, an den Inhalt der Seite <em>in Clojure</em> zu kommen.</p>

<p>Normalerweise kann man <a href="http://nakkaya.com/2010/06/15/clojure-io-cookbook/">einfach</a> einen Reader öffnen und den Inhalt einlesen:</p>

<div id="wpshdo_3" class="wp-synhighlighter-outer"><div id="wpshdt_3" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_3"></a><a id="wpshat_3" class="wp-synhighlighter-title" href="#codesyntax_3"  onClick="javascript:wpsh_toggleBlock(3)" title="Click to show/hide code block">Code block</a></td><td align="right"><a href="#codesyntax_3" onClick="javascript:wpsh_code(3)" title="Show code only"><img border="0" style="border: 0 none" src="http://blog.gungfu.de/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_3" onClick="javascript:wpsh_print(3)" title="Print code"><img border="0" style="border: 0 none" src="http://blog.gungfu.de/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://blog.gungfu.de/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://blog.gungfu.de/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_3" class="wp-synhighlighter-inner" style="display: block;"><pre class="clojure" style="font-family:monospace;"><span class="br0">&#40;</span><span class="kw1">defn</span> fetch<span class="sy0">-</span>url <span class="br0">&#91;</span>address<span class="br0">&#93;</span>
  <span class="br0">&#40;</span><span class="kw1">with-open</span> <span class="br0">&#91;</span>stream <span class="br0">&#40;</span><span class="sy0">.</span>openStream <span class="br0">&#40;</span>java<span class="sy0">.</span>net<span class="sy0">.</span>URL<span class="sy0">.</span> address<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#93;</span>
    <span class="br0">&#40;</span><span class="kw1">let</span>  <span class="br0">&#91;</span>buf <span class="br0">&#40;</span>java<span class="sy0">.</span>io<span class="sy0">.</span>BufferedReader<span class="sy0">.</span> 
                <span class="br0">&#40;</span>java<span class="sy0">.</span>io<span class="sy0">.</span>InputStreamReader<span class="sy0">.</span> stream<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#93;</span>
      <span class="br0">&#40;</span><span class="kw1">apply</span> <span class="kw1">str</span> <span class="br0">&#40;</span><span class="kw1">line-seq</span> buf<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span></pre></div></div>

<p>In diesem Fall ging das aber nicht so einfach: die Seite enthält personenbezogene Date und ist gesichert, wie es sein sollte (sprich: Login, Cookies und was-weiß-ich). Da man von diesen Sicherheitsmaßnahmen im IE nichts mitbekommt, war es naheliegend, die IE-Engine zu verwenden, um auf den HTML-Source abzuziehen. Das roch nach COM&#8230;</p>

<p>Tja, Ok. Clojure ist eine JVM-Sprache. Und in Java ist es mit Bordmitteln nicht möglich mal einfach so auf Plattformspezifika wie COM zuzugreifen. Es gibt aber scheinbar gute Bibliotheken für den COM-Zugriff wie <a href="http://sourceforge.net/projects/jacob-project/">Jacob</a> und <a href="http://www.j-interop.org/">j-Interop</a> &#8211; ich habe sie aber (noch) nicht genutzt, weil&#8230;</p>

<p>&#8230;COM ist von Microsoft. Die CLR auch. Und, hey, es gibt einen <a href="https://github.com/richhickey/clojure-clr">Port von Clojure auf die CLR</a>. Meine Überlegung war daher: Mit der .Net-Version von Clojure sollte der COM-Zugriff wesentich einfacher sein, als Java solche Plattformspezifika zu entlocken.</p>

<p>Naja, als ich gemerkt hatte, dass dem nicht unbedingt so ist &#8211; was nicht ausschließlich an Clojure lag, war&#8217;s auch schon zu spät. Ursprünglich wollte ich &#8220;einfach&#8221; <a href="http://www.c-sharpcorner.com/UploadFile/gcorrell/IEInstance12062005003909AM/IEInstance.aspx">folgenden Code</a> nach Clojure-CLR portieren:</p>

<div id="wpshdo_4" class="wp-synhighlighter-outer"><div id="wpshdt_4" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_4"></a><a id="wpshat_4" class="wp-synhighlighter-title" href="#codesyntax_4"  onClick="javascript:wpsh_toggleBlock(4)" title="Click to show/hide code block">Code block</a></td><td align="right"><a href="#codesyntax_4" onClick="javascript:wpsh_code(4)" title="Show code only"><img border="0" style="border: 0 none" src="http://blog.gungfu.de/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_4" onClick="javascript:wpsh_print(4)" title="Print code"><img border="0" style="border: 0 none" src="http://blog.gungfu.de/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://blog.gungfu.de/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://blog.gungfu.de/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_4" class="wp-synhighlighter-inner" style="display: block;"><pre class="csharp" style="font-family:monospace;"><span class="kw1">using</span> <span class="co3">SHDocVw</span><span class="sy0">;</span>
&nbsp;
<span class="kw1">public</span> <span class="kw1">void</span> OpenBrowser<span class="br0">&#40;</span><span class="kw4">string</span> url<span class="br0">&#41;</span>
<span class="br0">&#123;</span> 
    <span class="kw4">object</span> o <span class="sy0">=</span> null<span class="sy0">;</span>
    SHDocVw.<span class="me1">InternetExplorer</span> ie <span class="sy0">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span class="kw3">new</span></a>
    SHDocVw.<span class="me1">InternetExplorerClass</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
    IWebBrowserApp wb <span class="sy0">=</span> <span class="br0">&#40;</span>IWebBrowserApp<span class="br0">&#41;</span> ie<span class="sy0">;</span>
    wb.<span class="me1">Visible</span> <span class="sy0">=</span> true<span class="sy0">;</span>
    <span class="co1">//Do anything else with the window here that you wish</span>
    wb.<span class="me1">Navigate</span><span class="br0">&#40;</span>url, <span class="kw1">ref</span> o, <span class="kw1">ref</span> o, <span class="kw1">ref</span> o, <span class="kw1">ref</span> o<span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span></pre></div></div>


<p>Zunächst war mir nicht ganz klar, wie ich an <a href="http://www.codeproject.com/KB/toolbars/MicrosoftMshtml.aspx">SHDocVw</a> kommen könnte. Eine Interop-Assembly war (natürlich) die Lösung. Leider ist es war: <a href="Visual Studio rots your mind">Visual Studio rots your mind</a>&#8230; Durch die Toolunterstützung im Studio &#8220;vergißt&#8221; man recht schnell, was unter der Haube alles passiert. Und Emacs hilft an der Stelle echt nicht weiter. <img src='http://blog.gungfu.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>

<p>Am Ende dieser Episode bin ich aber an den ref-Parametern von Navigate gescheitert: auch ein <code>by-ref</code> in clojure-clr half da nicht (wenn ich mich recht erinnere hatte ich Fehlermeldungen vonwegen void könne nicht nach object &#8211; was weiß ich).</p>

<p>Als Alternative bin ich auf <a href="http://watin.org/"><em>Watin</em></a> gestoßen &#8211; ein Testing-Framework für Internetanwendungen, mit dem man programmatisch auf verschiedene Browser (auch IE) zugreifen kann.<br />
Das Objektmodell fand ich ein wenig umständlich &#8211; aber nach einer ausreichend langen Property-Kettenabfrage (in clojure-clr erledigt man den lesenden Zugriff per <code>get_</code> vor dem eigentlichen Propertynamen) kommt man ans innerHTML &#8211; sprich dem gesuchten Seiteninhalt:</p>

<div id="wpshdo_5" class="wp-synhighlighter-outer"><div id="wpshdt_5" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_5"></a><a id="wpshat_5" class="wp-synhighlighter-title" href="#codesyntax_5"  onClick="javascript:wpsh_toggleBlock(5)" title="Click to show/hide code block">Code block</a></td><td align="right"><a href="#codesyntax_5" onClick="javascript:wpsh_code(5)" title="Show code only"><img border="0" style="border: 0 none" src="http://blog.gungfu.de/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_5" onClick="javascript:wpsh_print(5)" title="Print code"><img border="0" style="border: 0 none" src="http://blog.gungfu.de/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://blog.gungfu.de/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://blog.gungfu.de/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_5" class="wp-synhighlighter-inner" style="display: block;"><pre class="clojure" style="font-family:monospace;"><span class="br0">&#40;</span><span class="kw1">defn</span> get<span class="sy0">-</span>content <span class="br0">&#91;</span><span class="sy0">^</span>String url<span class="br0">&#93;</span>
  <span class="br0">&#40;</span><span class="kw1">let</span> <span class="br0">&#91;</span>ie <span class="br0">&#40;</span>IE<span class="sy0">.</span> url<span class="br0">&#41;</span>
        content <span class="br0">&#40;</span><span class="sy0">-&gt;</span> ie
                    <span class="sy0">.</span>get_NativeBrowser
                    <span class="sy0">.</span>get_NativeDocument
                    <span class="sy0">.</span>get_Body
                    <span class="sy0">.</span>get_AsHtmlElement
                    <span class="sy0">.</span>get_innerHTML<span class="br0">&#41;</span><span class="br0">&#93;</span>
    <span class="br0">&#40;</span><span class="sy0">.</span>Close ie<span class="br0">&#41;</span>
    content<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></div></div>

<p>Zum Abschluß war noch zu beachten, dass das IE-Objekt auf einem Thread initiiert werden muss, der im <a class="wikiLink" href="http://wiki.gungfu.de/Main/ApartmentState">ApartmentState</a> STA läuft.<br />
Also muss ein ebensolcher Thread neu angelegt werden &#8211; in dem lasse ich dann die gesamte Verarbeitung ablaufen:</p>

<div id="wpshdo_6" class="wp-synhighlighter-outer"><div id="wpshdt_6" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_6"></a><a id="wpshat_6" class="wp-synhighlighter-title" href="#codesyntax_6"  onClick="javascript:wpsh_toggleBlock(6)" title="Click to show/hide code block">Code block</a></td><td align="right"><a href="#codesyntax_6" onClick="javascript:wpsh_code(6)" title="Show code only"><img border="0" style="border: 0 none" src="http://blog.gungfu.de/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_6" onClick="javascript:wpsh_print(6)" title="Print code"><img border="0" style="border: 0 none" src="http://blog.gungfu.de/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://blog.gungfu.de/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://blog.gungfu.de/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_6" class="wp-synhighlighter-inner" style="display: block;"><pre class="clojure" style="font-family:monospace;"><span class="br0">&#40;</span><span class="kw1">defn</span> start<span class="sy0">-</span>thread <span class="br0">&#91;</span>func<span class="br0">&#93;</span>
  <span class="br0">&#40;</span><span class="kw1">let</span> <span class="br0">&#91;</span>worker <span class="br0">&#40;</span>gen<span class="sy0">-</span>delegate ThreadStart <span class="br0">&#91;</span><span class="br0">&#93;</span> <span class="br0">&#40;</span>func<span class="br0">&#41;</span><span class="br0">&#41;</span>
        thread <span class="br0">&#40;</span><span class="kw1">doto</span> <span class="br0">&#40;</span>Thread<span class="sy0">.</span> worker<span class="br0">&#41;</span>
                 <span class="br0">&#40;</span><span class="sy0">.</span>SetApartmentState ApartmentState<span class="sy0">/</span>STA<span class="br0">&#41;</span>
                 <span class="br0">&#40;</span><span class="sy0">.</span>Start<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#93;</span>
    thread<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></div></div>

<p>Aufgerufen werden kann das dann mit:</p>
<div id="wpshdo_7" class="wp-synhighlighter-outer"><div id="wpshdt_7" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_7"></a><a id="wpshat_7" class="wp-synhighlighter-title" href="#codesyntax_7"  onClick="javascript:wpsh_toggleBlock(7)" title="Click to show/hide code block">Code block</a></td><td align="right"><a href="#codesyntax_7" onClick="javascript:wpsh_code(7)" title="Show code only"><img border="0" style="border: 0 none" src="http://blog.gungfu.de/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_7" onClick="javascript:wpsh_print(7)" title="Print code"><img border="0" style="border: 0 none" src="http://blog.gungfu.de/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://blog.gungfu.de/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://blog.gungfu.de/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_7" class="wp-synhighlighter-inner" style="display: block;"><pre class="clojure" style="font-family:monospace;"><span class="br0">&#40;</span>start<span class="sy0">-</span>thread #<span class="br0">&#40;</span>get<span class="sy0">-</span>content url<span class="br0">&#41;</span><span class="br0">&#41;</span></pre></div></div>

<p>Das HTML-Scraping mit dem regulären Ausdruck hat dann auch funktioniert.</p>

<p>Als nächstes ist Excel dran &#8211; vielleicht muss ich dann doch shdocvw verwenden (in der CLR-Welt) oder ich versuche mal Jacob/JInterop auf der JVM&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.gungfu.de/archives/2011/05/25/automatisieren-von-internetexplorer-und-ein-bisschen-html-scraping-mit-clojure-clr/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

