<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" version="2.0">

<channel>
	<title>True Solutions</title>
	
	<link>http://www.truesolutions.pl/blog</link>
	<description>Startup w Polsce. Refleksje, przemyślenia, rozwiązania.</description>
	<lastBuildDate>Thu, 07 Jan 2010 23:28:18 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<image>
  <link>http://www.truesolutions.pl/blog</link>
  <url>http://www.truesolutions.pl/blog/favicon.ico</url>
  <title>True Solutions</title>
</image>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/TrueSolutions" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="truesolutions" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Pobieranie nowych wiadomości przez JavaMail</title>
		<link>http://www.truesolutions.pl/blog/pobieranie-nowych-wiadomosci-przez-javamail</link>
		<comments>http://www.truesolutions.pl/blog/pobieranie-nowych-wiadomosci-przez-javamail#comments</comments>
		<pubDate>Thu, 07 Jan 2010 23:28:18 +0000</pubDate>
		<dc:creator>Wiktor</dc:creator>
				<category><![CDATA[Inżynieria oprogramowania]]></category>

		<guid isPermaLink="false">http://www.truesolutions.pl/blog/?p=244</guid>
		<description><![CDATA[I tylko nowych.
Stanąłem przed problemem jak efektywnie pobierać maile ze skrzynek POP3 za pomocą JavaMail w przypadku, gdy pobrane wiadomości nie są usuwane z serwera. Oczywiście głównym problemem jest wygenerowanie listy wiadomości, które znajdują się w skrzynce odbiorczej konta POP3, a nie znajdują się jeszcze w lokalnej bazie.
Do tej pory w Funneli stosowaliśmy prosty i, [...]]]></description>
			<content:encoded><![CDATA[<p>I tylko nowych.</p>
<p>Stanąłem przed problemem jak <strong>efektywnie</strong> pobierać maile ze skrzynek POP3 za pomocą JavaMail w przypadku, gdy pobrane wiadomości nie są usuwane z serwera. Oczywiście głównym problemem jest wygenerowanie listy wiadomości, które znajdują się w skrzynce odbiorczej konta POP3, a nie znajdują się jeszcze w lokalnej bazie.</p>
<p>Do tej pory w Funneli stosowaliśmy prosty i, wydawałoby się, efektywny algorytm:</p>
<ol>
<li>Sprawdź kiedy pobrano ostatnią wiadomość z tego konta</li>
<li>Wyszukaj nowsze wiadomości (uwzględniając kilkugodzinny margines)</li>
<li>Pobierz wiadomości pomijając już pobrane</li>
</ol>
<p>W Javie wyglądało to mniej więcej tak:</p>
<blockquote>
<pre>folder.open( Folder.READ_WRITE );
Date d = ... //tu pobranie z bazy daty ostatnio odebranego maila
SentDateTerm onlyRecent = new SentDateTerm( DateTerm.GE, d );
Message[] msgs = folder.search( onlyRecent ); //wyszukanie tylko nowszych, które pobiera pełne nagłówki - tu jest problem
for ( Message m: msgs ){
	com.sun.mail.pop3.POP3Folder pf = (com.sun.mail.pop3.POP3Folder)folder;
	String uid = pf.getUID( m );
	bool exists = ... //sprawdzenie czy uid już jest w bazie
	if ( ! exists ){
		//pobranie maila i zapis do bazy
	}
}</pre>
</blockquote>
<p>Okazuje się, że JavaMail, aby móc porównać daty, pobiera <strong>całe</strong> nagłówki <strong>wszystkich</strong> maili. W sieci znalazłem informację, ze średnio nagłówek zajmuje ok 1kB (nie sprawdzałem). Przy skrzynce z 5000 maili daje to jakieś 5MB do pobrania&#8230; co 30 sekund.<br />
Na szczęście istnieje bardziej efektywny sposób &#8211; pobrać identyfikatory wszystkich maili za pomocą metody fetch() i nie wykonywać punktu 2, czyli porównywania dat:</p>
<blockquote>
<pre>folder.open( Folder.READ_WRITE );
Message[] msgs = folder.getMessages();
FetchProfile fp = new FetchProfile();
fp.add( UIDFolder.FetchProfileItem.UID );
folder.fetch( msgs, fp ); //wstępne pobranie identyfikatorów
for ( Message m: msgs ){
	com.sun.mail.pop3.POP3Folder pf = (com.sun.mail.pop3.POP3Folder)folder;
	String uid = pf.getUID( m );
	bool exists = ... //sprawdzenie czy uid już jest w bazie
	if ( ! exists ){
		//pobranie maila i zapis do bazy
	}
}</pre>
</blockquote>
<p>Na pierwszy rzut oka takie rozwiązanie wydaje się mniej efektywne. W końcu pobieramy pełną listę wiadomości i po kolei, dla każdej pozycji, sprawdzamy czy nie została już pobrana. W praktyce okazuje się, że różnica w ilości przesyłanych danych w przypadku gdy pobieramy całe nagłówki do wyszukiwania po dacie, a sytuacji gdy pobierane są jedynie unikalne identyfikatory, jest tak ogromna, że czas sprawdzania czy wiadomość znajduje się w lokalnej bazie jest praktycznie pomijalny.</p>
<p>W przeprowadzonych testach w skrajnych przypadkach zysk czasu był <strong>tysiąckrotny</strong>.</p>
<img src="http://feeds.feedburner.com/~r/TrueSolutions/~4/S9FscIZnWFg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.truesolutions.pl/blog/pobieranie-nowych-wiadomosci-przez-javamail/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java (od Apple): zaskakujące update’y</title>
		<link>http://www.truesolutions.pl/blog/java-kompilacja-a-updatey</link>
		<comments>http://www.truesolutions.pl/blog/java-kompilacja-a-updatey#comments</comments>
		<pubDate>Thu, 10 Dec 2009 15:09:46 +0000</pubDate>
		<dc:creator>Wiktor</dc:creator>
				<category><![CDATA[Bez kategorii]]></category>

		<guid isPermaLink="false">http://www.truesolutions.pl/blog/?p=231</guid>
		<description><![CDATA[Poniższy problem starych wyjadaczy Javy pewnie nie zaskoczy, ale ja ani za Javą nie przepadam, ani jej zbyt często nie używam, więc lekko mnie zdziwił&#8230;
Dzisiaj postanowiłem poprawić drobny błąd przy konwertowaniu maili z HTML na czysty tekst. Poprawa trywialna: kilka wywołań replaceAll() i po kłopocie. Ale&#8230;
Po wrzuceniu poprawki na produkcję, przy wysyłaniu maili, pojawił się [...]]]></description>
			<content:encoded><![CDATA[<p><em>Poniższy problem starych wyjadaczy Javy pewnie nie zaskoczy, ale ja ani za Javą nie przepadam, ani jej zbyt często nie używam, więc lekko mnie zdziwił&#8230;</em></p>
<p>Dzisiaj postanowiłem poprawić drobny błąd przy konwertowaniu maili z HTML na czysty tekst. Poprawa trywialna: kilka wywołań replaceAll() i po kłopocie. Ale&#8230;</p>
<p>Po wrzuceniu poprawki na produkcję, przy wysyłaniu maili, pojawił się błąd:</p>
<blockquote><p>javax.mail.MessagingException: Could not connect to SMTP host: xxxxxxxxxx, port: 25;<br />
nested exception is:<br />
java.net.SocketException: java.lang.ClassNotFoundException: Cannot find the specified class aaaaa.yyyyy</p></blockquote>
<p>Błąd oczywiście zupełnie nie związany z wprowadzonymi poprawkami.<br />
Okazało się, że ostatnia (zaintalowałem ją wczoraj) poprawka Javy od Apple zmienia nieco zachowanie kompilatora. Klasa potrzebna do zestawienia połączenia SSL (wyżej nazwana aaaaa.yyyyy) jest ładowana dynamicznie przez wskazanie jej jako dostawcy gniazda przy połączeniach SSL:</p>
<blockquote><p>Security.setProperty( &#8220;ssl.SocketFactory.provider&#8221;, SSL_PROVIDER );</p></blockquote>
<p>Pomimo iż w nagłówku pliku z klasą gdzie ww instrukcja się pojawiła widniała dyrektywa:</p>
<blockquote><p>import aaaaa.*;</p></blockquote>
<p>Kompilator postanowił nie kompilować potrzebnej klasy, bo nie była ona jawnie użyta. Wcześniej nie było tego problemu i wszystkie klasy wpisane w import były kompilowane, niezależnie czy kompilator wykrył, że są używane, czy też nie.</p>
<p>Rozwiązanie jest oczywiście trywialne &#8211; nie należy polegać na wykrywaniu zależności przez kompilator i trzeba ręcznie (jawnie w skrypcie kompilacji) skompilować potrzebne klasy.</p>
<p>IMHO to dość istotna zmiana w zachowaniu kompilatora jak na poprawkę nie zmieniającą nawet numeru wersji (nazwali ją Java for Max OS X 10.6 Update 1)</p>
<p>To nie pierwszy raz, kiedy Apple zaskoczyło mnie poprawką Javy, która spowodowała problemy z naszym systemem.</p>
<img src="http://feeds.feedburner.com/~r/TrueSolutions/~4/Lu9bCilGLc0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.truesolutions.pl/blog/java-kompilacja-a-updatey/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hi, I’m not a PC. Na szczęście.</title>
		<link>http://www.truesolutions.pl/blog/hi-im-not-a-pc-na-szczescie</link>
		<comments>http://www.truesolutions.pl/blog/hi-im-not-a-pc-na-szczescie#comments</comments>
		<pubDate>Mon, 07 Dec 2009 13:46:42 +0000</pubDate>
		<dc:creator>Wiktor</dc:creator>
				<category><![CDATA[Przemyślenia]]></category>

		<guid isPermaLink="false">http://www.truesolutions.pl/blog/?p=204</guid>
		<description><![CDATA[Disclaimer: Nie chcę tutaj rozpętać jakiegoś flamewara. Pomimo, że jestem fanem Apple to nigdy na siłę nie udowadniałem nikomu wyższości rozwiązań tej firmy (szczególnie jeśli chodzi o sprzęt). Jak ktoś woli PC to szanuję jego wybór. Oczywiście dopóki nie każe mi przy nim pracować. Wpis dotyczy sprzętu, a od jakiegoś czasu Maci to zwykłe PC-ty, [...]]]></description>
			<content:encoded><![CDATA[<p><em>Disclaimer: Nie chcę tutaj rozpętać jakiegoś flamewara. Pomimo, że jestem fanem Apple to nigdy na siłę nie udowadniałem nikomu wyższości rozwiązań tej firmy (szczególnie jeśli chodzi o sprzęt). Jak ktoś woli PC to szanuję jego wybór. Oczywiście dopóki nie każe mi przy nim pracować. Wpis dotyczy sprzętu, a od jakiegoś czasu Maci to zwykłe PC-ty, tylko w ładniejszej obudowie i z mniejszą liczbą portów.</em></p>
<p>Właśnie na <a href="http://technologie.gazeta.pl/technologie/1,82011,7337347,Maki_znow_najmniej_awaryjne.html" target="_blank">gazeta.pl</a> znalazłem informację o rankingu awaryjności komputerów. Według tego rankingu Apple to najbardziej niezawodne komputery.</p>
<p>Od 5 lat jestem użytkownikiem komputerów Apple. Właściwie to notebooków, z komputerami stacjonarnymi większej styczności nie miałem. Pozwólcie, że przytoczę historię (z punktu widzenia awaryjności) moich komputerów tej firmy:</p>
<p><br/></p>
<h3>Rozdział pierwszy: listopad 2004 &#8211; wrzesień 2006, iBook G4 12&#8243;</h3>
<p><br/></p>
<p>Pierwszy komputer Apple w moich rękach i zaraz pierwszy notebook w moim posiadaniu. Dlaczego zdecydowałem się na Apple, pomimo że nigdy komputerów tej firmy nie używałem, pozwolę sobie pominąć. Najbardziej niezawodny notebook jakiego miałem. Do czasu.</p>
<p>1. kilka (5 jeśli dobrze pamiętam) dni przed końcem 12-miesiecznej gwarancji katastrofa &#8211; martwa płyta główna. Czas oczekiwania na nową: prawie miesiąc.</p>
<p>2. komputer wraca, ale źle złożony. Ponieważ wtedy naprawy gwarancyjne komputerów Apple serwisował tylko SAD w Warszawie, aby nie tracić czasy problem postanowiłem rozwiązać sam</p>
<p>3. prawie po roku od wymiany płyty déjà vu &#8211; martwa płyta. Niestety gwarancja już dawno minęła.</p>
<p>Po drodze komputer załapał się na program wymiany baterii. Stara bateria była sprawna do ostatnich dni (tak, nie odesłałem jej &#8211; przepraszam).</p>
<p>Dwa lata używania to akurat dobry moment na update sprzętu. Apple akurat przeszedł na procesory Intela, więc i tak czas pozbyć się architektury PowerPC z biurka. Co prawda do teraz uważam, że PowerPC był lepszy niż x86, ale to temat na oddzielny wpis.</p>
<p><br/></p>
<h3>Rozdział drugi: od września 2006, MacBook White CoreDuo</h3>
<p><br/></p>
<p>Problemy dotyczące wszystkich wczesnych MacBooków nie mogły mnie ominąć:</p>
<p>1. mrugająca matryca &#8211; problem rozwiązałem dopiero niedawno przyklejając kabelek zasilający do inwertera</p>
<p>2. żółknąca i pękająca obudowa &#8211; no comment</p>
<p>A dalej:</p>
<p>3. padł napęd DVD. Ok, nie używałem go zbyt intensywnie więc żadna strata :)</p>
<p>4. zasilacz. Najpierw wtyczka sama nie wiedziała czy chce świecić czy nie i czasami podłączała się tak, że bateria się nie ładowała (prawdopodobnie coś z tymi bolcami w MagSafe było nie tak). Potem pękł kabelek przy samej obudowie zasilacza &#8211; nie mam pojęcia jak to się stało.</p>
<p>5. bateria. W dwa lata zajechałem dwie. Te w iBooku były zdecydowanie lepsze. Jacek z resztą też wymieniał baterię w MacBooku, więc coś musi być na rzeczy</p>
<p>I tak sukces: komputer, pomimo zalania kawą i koniecznością wymiany klawiatury, działa do dzisiaj (wykluczając DVD i słabą baterię &#8211; trzeciej nie kupiłem)</p>
<p><br/></p>
<h3>Rozdział trzeci: od listopada 2008, MacBook Pro Unibody 15.4&#8243;</h3>
<p><br/></p>
<p>Do trzech razy sztuka, cza na (naj)wyższą półkę. Zamawiam mojego MBP na długo zanim kontener przypływa do Polski. W zakupie pomaga mi PFRON &#8211; polecam :)</p>
<p>Teraz też pojawiają sie problemy wieku niemowlęcego:</p>
<p>1. już w pierwszych dniach zauważam coś niepokojącego: notebook budzi się samoczynnie.</p>
<p>2. touchpad ma humory: czasami kliknięcie działa, czasami nie</p>
<p>Na szczęście przyczyną obu problemów był firmware. Dwa update&#8217;y i problemy znikają. Ale:</p>
<p>3. bardzo ciekawie działa układ sterujący wentylatorami. Notebook jest cichy, czasami za bardzo. Szczególnie wtedy gdy temperatura wynosi prawie 100 stopni&#8230; Mój prywatny rekord: 105 stopni. Problem pojawia się na szczęscie tylko przy dużym obciążeniu karty graficznej. Rozwiązanie: <a href="http://www.eidac.de/" target="_blank">smcFanControl</a> i ręczne ustawienie wentylatorów na maxa przed włączeniem Call of Duty 4</p>
<p>Ok, powyższe problemy w sumie nie są uciążliwe lub zostały szybko rozwiązanie. Teraz ciekawsze:</p>
<p>4. Pewnego dnia otworzyłem notebooka i ujrzałem coś takiego:</p>
<p><img class="alignnone size-large wp-image-208" title="Awaria matrycy" src="http://www.truesolutions.pl/blog/wp-content/uploads/2009/12/IMG_0143-1024x768.jpg" alt="Awaria matrycy" width="500" height="375" /></p>
<p>Przy poruszaniu czasami udawało się zmusić matrycę do działania &#8211; oczywista diagnoza: złamany kabelek.</p>
<p>Zawiozłem notebooka do serwisu firmy <a href="http://cortland.pl" target="_blank">Cortland</a> w Poznaniu. Szybka diagnoza (taka sama jak moja) i informacja: ściągamy nową matrycę. Tak, ktoś nie przewidział, że kabelek idący przez otwierany kilka razy dzienne zawias może się złamać i postanowił go zakleić wewnątrz matrycy. Super! Na szczęście DisplayPort działa bez zarzutu. Biorę notebooka do domu i działam na zewnętrznym monitorze. Po paru dniach przybywa matryca. Szybka wymiana i&#8230; nie działa AirPort. A właściwie to został wyjęty i nie włożony z powrotem. Tydzień czekania, AirPort wraca na miejsce. Jeszcze dwie wycieczki do Cortlandu bo komputer był źle złożony: brak podświetlenia matrycy i odstający plastik oraz ostatnia naprawa korespondencyjna &#8211; pan Rafał (pozdrawiam!) zapomniał wkręcić dwóch śrubek w obudowę. Nie chciałem już go nachodzić, więc poprosiłem o wysłanie tych śrubek pocztą.</p>
<p>5. Na koniec jeszcze ciekawostka: chipset nVidii nie obsługuje niektórych (tak, tych bardziej popularnych) kości RAM, gdy wsadzimy dwie po 2GB. Ok, jest lista pamięci kompatybilnych i te działają, nie można więc nazwać tego usterką. Ale sorry, od czegoś są standardy i wypadałoby żeby je stosować&#8230;</p>
<p>Z przezorności przedłużyłem gwarancję do 3 lat. Lepiej dmuchać na zimne (o ile tak można powiedzieć o czymś, co ma temperaturę wrzątku).</p>
<p><br/></p>
<h3>Konkluzja</h3>
<p><br/></p>
<p>Bardzo cieszę się, że jestem użytkownikiem najmniej awaryjnego sprzętu (według mnie i tak zbyt awaryjnego) i bardzo serdecznie gratuluję Apple zajęcia tak wysokiej pozycji w rankingu. Jeśli problemów z najmniej awaryjnym sprzętem nie udało mi się zmieścić na jednej stronie A4, to na prawdę bardzo się cieszę, że nie jestem posiadaczem sprzętu firm ze środka, bądź, o zgrozo, z dołu rankingu. Tym bardziej raduje mnie fakt, że nie mam notebooka składanego przez pana Kazia w jego Przedsiębiorstwie Produkcyjno-Handlowym z podzespołów przeznaczonych do komputerów stacjonarnych.</p>
<p>Dlaczego, pomimo licznych problemów, zdecydowałem się pozostać wiernym firmie Apple? Być może dlatego, że oprócz niezawodności komputery cechują się też innymi rzeczami: wydajnością, ergonomią, designem, oprogramowaniem. Szczególnie w trzech ostatnich, IMHO (patrz Disclaimer), Apple jest liderem. Lubię czasami zamknąć mojego MBP, położyć obok otwartego HP, czy Toshiby o podobnych parametrach i bez słowa komentarza porównać ich wysokość&#8230; Młotek jest na pewno mniej awaryjny, ale jakoś i tak wolę pracować na Macu.</p>
<p>Edit [2009-12-16]:<br />
Po kilku dniach od opublikowania tego posta, Apple wydało aktualizację EFI dla MBP, której zadaniem było wyciszenie DVD buczącego przy starcie i budzeniu się komputera. Wygląda na to, że ta poprawka rozwiązuje również opisany wyżej problem przegrzewania się. Grejt sukcess!</p>
<img src="http://feeds.feedburner.com/~r/TrueSolutions/~4/cQu_qWvGnE8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.truesolutions.pl/blog/hi-im-not-a-pc-na-szczescie/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>SSH – ułatwiamy sobie życie</title>
		<link>http://www.truesolutions.pl/blog/ssh-ulatwiamy-sobie-zycie</link>
		<comments>http://www.truesolutions.pl/blog/ssh-ulatwiamy-sobie-zycie#comments</comments>
		<pubDate>Sat, 28 Nov 2009 14:05:14 +0000</pubDate>
		<dc:creator>Wiktor</dc:creator>
				<category><![CDATA[Bez kategorii]]></category>

		<guid isPermaLink="false">http://www.truesolutions.pl/blog/?p=197</guid>
		<description><![CDATA[Postanowiłem zebrać dla potomnych (i dla siebie, w razie jakbym czegoś zapomniał) kilka informacji, które ułatwią używanie tego narzędzia oraz pokać inne potencjalne zastosowania inne niż zdalne logowanie.
Automatyczna autoryzacja
Logowanie do zdalnej maszyny jest trywialne:
ssh -llogin nazwa-serwera
potem podajemy hasło i gotowe. Problem pojawia się gdy hasło wygląda tak:
z7kw=TQksHO!CVGSMXmX#5K42hK@ePMQs6(YS
SSH (na szczęście) nie pamięta haseł, ani nie pozwala [...]]]></description>
			<content:encoded><![CDATA[<p>Postanowiłem zebrać dla potomnych (i dla siebie, w razie jakbym czegoś zapomniał) kilka informacji, które ułatwią używanie tego narzędzia oraz pokać inne potencjalne zastosowania inne niż zdalne logowanie.</p>
<p><strong>Automatyczna autoryzacja</strong></p>
<p>Logowanie do zdalnej maszyny jest trywialne:</p>
<blockquote><p>ssh -llogin nazwa-serwera</p></blockquote>
<p>potem podajemy hasło i gotowe. Problem pojawia się gdy hasło wygląda tak:</p>
<blockquote><p>z7kw=TQksHO!CVGSMXmX#5K42hK@ePMQs6(YS</p></blockquote>
<p>SSH (na szczęście) nie pamięta haseł, ani nie pozwala podawać ich w postaci przełącznika (wtedy można by zapisać hasło w jakimś skrypcie). Jest jednak proste rozwiązania tego problemu &#8211; autoryzacja przez parę: klucz prywatny &#8211; klucz publiczny.</p>
<p>Cała operacja sprowadza się do trzech kroków: wygenerowania ww. pary, umieszczenia w ustawieniach użytkownika klucza prywatnego i skopiowania na maszynę zdalną klucza prywatnego.</p>
<p>Nie będę przepisywał sczegółowej instrukcji, którą znajdziecie tutaj: <a href="http://www.csua.berkeley.edu/~ranga/notes/ssh_nopass.html" target="_blank">http://www.csua.berkeley.edu/~ranga/notes/ssh_nopass.html</a></p>
<p><strong>Aliasy</strong></p>
<p>Wpisanie nazwy użytkownika i nazwy serwera jako argumentów polecenia nie jest zbyt kłopotliwe, dopóki nie wygląda to tak (przykład skrajny :) ):</p>
<blockquote><p>ssh -p 1234 -leustachybrzeczyszczykiewicz serwer-osiemnasty.szafa-trzydziestadruga.siec-szkieletowa.funnela.com</p></blockquote>
<p>Z pomocą przychodzi plik konfiguracyjny, który dostępny jest pod ścieżką ~/.ssh/config (jak go nie ma, to trzeba sobie zrobić).</p>
<p>Można w nim ustawić na prawdę wiele rzeczy (zachęcam do lektury: man ssh_config ), ale nas w tej chwili interesuje najbardziej trywialna: aliasy.</p>
<p>Po dodaniu takiego wpisu do konfiguracji:</p>
<blockquote><p>Host s18s32</p>
<p><span style="white-space:pre"> </span>HostName serwer-osiemnasty.szafa-trzydziestadruga.siec-szkieletowa.funnela.com</p>
<p><span style="white-space:pre"> </span>Port 1234</p>
<p><span style="white-space:pre"> </span>User eustachybrzeczyszczykiewicz</p>
<p><span style="white-space:pre"> </span>HostKeyAlias serwer18szafa32</p></blockquote>
<p>pan Eustachy, aby dostać się na serwer osiemnasty w trzydziestej drugiej szafie wpisuje po prostu:</p>
<blockquote><p>ssh s18s32</p></blockquote>
<p>lub</p>
<blockquote><p>ssh serwer18szafa32</p></blockquote>
<p>I nie musi już pamiętać nazwy serwera, numeru portu czy nazwy użytkownika. Przede wszystkim nie musi tego za każdym razem wpisywać.</p>
<p><strong>Przekierowywanie portów</strong></p>
<p>Bardzo przydatną w specyficznych sytuacjach funkcją SSH jest możliwość przekierowania portów dowolnej zdalnej maszyny na komputer lokalny. Rozważmy taki przykład:</p>
<p>Nadgorliwy administrator sieci zablokował praktycznie wszystkie usługi. Nawet HTTP kuleje &#8211; nie da się wysłać większej porcji danych POST. Na szczęscie działa SSH. (tak jest skonfigurowana sieć Politechniki Poznańskiej).</p>
<p>My chcemy z takiej sieci zrobić commit SVN ( port: 3690 ) lub połączyć się z bazą danych.</p>
<p>Na pomoc przychodzi oczywiście SSH.</p>
<p>Przy okazji połączenia SSH stawiamy tunel, który mapuje porty jakiejś zdalnej maszyny (np. tej na którą logujemy się przez SSH) na porty lokalne.</p>
<p>W tym celu do pliku konfiguracyjnego dopisujemy linijkę w formacie:</p>
<blockquote><p>LocalForward &lt;port lokalny&gt; &lt;maszyna zdalna&gt;:&lt;port zdalny&gt;</p></blockquote>
<p>np:</p>
<blockquote><p>Host tunnel</p>
<p><span style="white-space:pre"> </span>HostName serwer-pierwszy.funnela.com</p>
<p><span style="white-space:pre"> </span>User root</p>
<p><span style="white-space:pre"> </span>LocalForward 3690 localhost:3690</p>
<p><span style="white-space:pre"> </span>LocalForward 5432 localhost:5432</p>
<p><span style="white-space:pre"> </span>LocalForward 8080 router.funnela.com:8080</p></blockquote>
<p>po zestawieniu połączenia ( ssh tunnel ), możemy połączyć się z komputerem lokalnym na porcie 3690 aby uzyskać połączenie z SVN na serwerze pierwszym. Analogicznie dla Postgresa.</p>
<p>Aby nie mieć w programach klienckich dwóch konfiguracji dla połączenia przez tunel ( połączenie z localhost ) i bezpośrednio, można zastosować prosty trick. Po połączeniu tunelu należy dodać do /etc/hosts wpis, który powiąże nazwę serwera ( serwer-pierwszy.funnela.com ) z adresem 127.0.0.1. Od tej chwili wszelkie połączenia SVN lub Postgres z serwer-pierwszy.funnela.com będą szły przez tunel i zgrabnie ominą firewalla.</p>
<p>Podobnie będą działały połączenia z localhost na porcie 8080, jednak tym razem zostaną przekierowane na zupełnie inną maszynę (router).</p>
<p><strong>SOCKS Proxy</strong></p>
<p>W celu ominięcia firewalla lub w przypadku konieczności połączenia się z użyciem innego zewnętrznego adresu IP, możemy również skorzystać z kolejnej przydatnej funkcji SSH &#8211; SOCKS proxy. Podczas nawiązywania połączenia ze zdalnym serwerem, możemy użyć przełącznika -D wraz z numerem lokalnego portu. Podczas takiego połączenia nasz komputer lokalny będzie działał jako serwer SOCKS. Wystarczy teraz w ustawieniach programu klienckiego (lub ustawieniach sieci np. w Max OS X) wskazać, żeby połączenie odbywało się przez serwer SOCKS pod adresem localhost na podanym wcześniej porcie. Możemy teraz cieszyć się połączeniem przekierowanym przez nasz serwer SSH.</p>
<p>Serwer proxy jest znacznie prostszy w konfiguracji niż przekierowywanie portów &#8211; nie wymaga konfiguracji każdej usługi oddzielnie. Ma jednak sporą wadę: nie wszystkie programy potrafią korzystać z proxy, więc jego zastosowanie ogranicza się głównie do przeglądarki internetowej.</p>
<p>Oczywiście połączenie przez SSH jest zawsze szyfrowane, więc korzystanie z SOCKS lub przekierowywania portów nie tylko pozwala ominąć blokadę portów w sieci, ale również chroni nas przed analizą pakietów przez dynamiczny firewall bądź przechwyceniem ich przez intruza.</p>
<img src="http://feeds.feedburner.com/~r/TrueSolutions/~4/ZmSmicZTSuQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.truesolutions.pl/blog/ssh-ulatwiamy-sobie-zycie/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>SELECT MAX(id) w PostgreSQL</title>
		<link>http://www.truesolutions.pl/blog/select-max_id_-w-postgresql</link>
		<comments>http://www.truesolutions.pl/blog/select-max_id_-w-postgresql#comments</comments>
		<pubDate>Thu, 01 Oct 2009 22:48:20 +0000</pubDate>
		<dc:creator>Wiktor</dc:creator>
				<category><![CDATA[Bazy danych]]></category>

		<guid isPermaLink="false">http://www.truesolutions.pl/blog/?p=182</guid>
		<description><![CDATA[Jak znaleźć najnowszą (czyt. o największym id) krotkę? Wydawałoby się, że nic prostrzego &#8211; wystarczy użyć funkcji agregującej MAX():
SELECT MAX( id ) FROM tab_a;
I rzeczywiście w większości przypadków MAX() zdaje egzamin i to bardzo dobrze. Na testowych danych zapytanie wykonywało się 0.05ms. Rozważmy jednak bardziej skomplikowany przypadek:
SELECT MAX( id ) FROM tab_a a JOIN tab_b [...]]]></description>
			<content:encoded><![CDATA[<p>Jak znaleźć najnowszą (czyt. o największym id) krotkę? Wydawałoby się, że nic prostrzego &#8211; wystarczy użyć funkcji agregującej MAX():</p>
<blockquote><p>SELECT MAX( id ) FROM tab_a;</p></blockquote>
<p>I rzeczywiście w większości przypadków MAX() zdaje egzamin i to bardzo dobrze. Na testowych danych zapytanie wykonywało się 0.05ms. Rozważmy jednak bardziej skomplikowany przypadek:</p>
<blockquote><p>SELECT MAX( id ) FROM tab_a a JOIN tab_b b ON ( a.xx = b.yy );</p></blockquote>
<p>I tutaj przestaje być wesoło. Powyższy przykład wykonywał się ponad 22ms, czyli prawie 500 razy dłużej! Oczywiście zarówno id jak i kolumny z warunku połączeniowego mają prawidłowe indeksy. Problem polega na tym, że wynik połączenia zaindeksowany już nie jest i MAX() wykonuje seq scan na tych danych.</p>
<p>Rozwiązanie jest trywialne &#8211; wystarczy nie używać MAX():</p>
<blockquote><p>SELECT id FROM tab_a a JOIN tab_b b ON ( a.xx = b.yy ) ORDER BY id DESC LIMIT 1;</p></blockquote>
<p>Rezultat: 0.12ms.</p>
<p>Poniżej dowód w postaci screenshotów z &#8220;życiowej&#8221; bazy (wybaczcie cenzurę &#8211; nie chcę ujawniać struktury bazy):</p>
<p><a href="http://www.truesolutions.pl/blog/wp-content/uploads/2009/09/max.png"><img class="alignnone size-medium wp-image-185" title="max()" src="http://www.truesolutions.pl/blog/wp-content/uploads/2009/09/max-300x221.png" alt="" width="300" height="221" /></a></p>
<p><a href="http://www.truesolutions.pl/blog/wp-content/uploads/2009/09/join-max.png"><img class="alignnone size-medium wp-image-186" title="max() z join" src="http://www.truesolutions.pl/blog/wp-content/uploads/2009/09/join-max-300x182.png" alt="" width="300" height="182" /></a></p>
<p><a href="http://www.truesolutions.pl/blog/wp-content/uploads/2009/09/join-limit1.png"><img class="alignnone size-medium wp-image-188" title="join z order desc limit 1" src="http://www.truesolutions.pl/blog/wp-content/uploads/2009/09/join-limit1-300x185.png" alt="" width="300" height="185" /></a></p>
<img src="http://feeds.feedburner.com/~r/TrueSolutions/~4/rD7zmb-5I7w" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.truesolutions.pl/blog/select-max_id_-w-postgresql/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>True Solutions Blog – reanimacja.</title>
		<link>http://www.truesolutions.pl/blog/true-solutions-blog-reanimacja</link>
		<comments>http://www.truesolutions.pl/blog/true-solutions-blog-reanimacja#comments</comments>
		<pubDate>Thu, 01 Oct 2009 22:42:32 +0000</pubDate>
		<dc:creator>Wiktor</dc:creator>
				<category><![CDATA[Inżynieria oprogramowania]]></category>

		<guid isPermaLink="false">http://www.truesolutions.pl/blog/?p=180</guid>
		<description><![CDATA[Ostatnimi czasy cała nasza energia jest skupiona wokół Funneli i zupełnie zaniedbaliśmy bloga firmowego na rzecz bloga naszego prostego rozwiązania CRM. Postanowiłem przywrócić do życie to miejsce, jednocześnie tworząc z niego &#8220;notatnik programisty&#8221;. Od teraz na blogu True Solutions będą się pojawiały bardzo krótkie wpisy z dziedziny szeroko pojętej inżynierii oprogramowania. Będą to wszelkie uwagi/spostrzeżenia/odkrycia/sztuczki [...]]]></description>
			<content:encoded><![CDATA[<p>Ostatnimi czasy cała nasza energia jest skupiona wokół <a href="http://funnela.com" target="_blank">Funneli</a> i zupełnie zaniedbaliśmy bloga firmowego na rzecz <a href="http://funnela.com/blog" target="_blank">bloga</a> naszego prostego rozwiązania CRM. Postanowiłem przywrócić do życie to miejsce, jednocześnie tworząc z niego &#8220;notatnik programisty&#8221;. Od teraz na blogu True Solutions będą się pojawiały bardzo krótkie wpisy z dziedziny szeroko pojętej inżynierii oprogramowania. Będą to wszelkie uwagi/spostrzeżenia/odkrycia/sztuczki na jakie napotkam się w pracy nad projektami (głownie Funnela, ale mogą pojawić się również jakieś <a href="http://www.cs.put.poznan.pl" target="_blank">akademickie</a> rozważania).</p>
<img src="http://feeds.feedburner.com/~r/TrueSolutions/~4/IMJmLPViyEI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.truesolutions.pl/blog/true-solutions-blog-reanimacja/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Trzy tysiące zmian w kodzie plus zdjęcie dinozaura</title>
		<link>http://www.truesolutions.pl/blog/trzy-tysiace-zmian-w-kodzie-plus-zdjecie-dinozaura</link>
		<comments>http://www.truesolutions.pl/blog/trzy-tysiace-zmian-w-kodzie-plus-zdjecie-dinozaura#comments</comments>
		<pubDate>Thu, 05 Feb 2009 20:25:14 +0000</pubDate>
		<dc:creator>Jacek</dc:creator>
				<category><![CDATA[Bez kategorii]]></category>
		<category><![CDATA[beta]]></category>
		<category><![CDATA[flux]]></category>
		<category><![CDATA[start-up]]></category>

		<guid isPermaLink="false">http://www.truesolutions.pl/blog/?p=161</guid>
		<description><![CDATA[Mamy okazję na małe święto &#8211; właśnie puściliśmy rewizję numer 3000 do SVN-a dla naszego projektu zwanego roboczo &#8220;Flux&#8221;.

Rewizja nr 3000 powędrowała do SVN-a
Wszystkich zainteresowanych efektami commit-ów zapraszamy na blog Fluksa oraz do zapisania się na beta testy.
Dodatkowo przenieśliśmy się na lepszy serwer, co pozwoliło zwolnić z pracy nasz poprzedni serwer deweloperski. Na zdjęciu macierz [...]]]></description>
			<content:encoded><![CDATA[<p>Mamy okazję na małe święto &#8211; właśnie puściliśmy rewizję numer 3000 do SVN-a dla <a href="http://flux.pl">naszego projektu</a> zwanego roboczo &#8220;Flux&#8221;.</p>
<p><a href="http://www.truesolutions.pl/blog/wp-content/uploads/2009/02/flux-3000-commit.jpg"><img src="http://www.truesolutions.pl/blog/wp-content/uploads/2009/02/flux-3000-commit.jpg" alt="Rewizja nr 3000 powędrowała do SVN-a" title="Rewizja nr 3000 powędrowała do SVN-a" width="400" height="183" class="size-full wp-image-165" /></a><br />
<em>Rewizja nr 3000 powędrowała do SVN-a</em></p>
<p>Wszystkich zainteresowanych efektami commit-ów zapraszamy na <a href="http://blog.flux.pl">blog Fluksa</a> oraz do zapisania się na <a href="http://blog.flux.pl/beta-testy/">beta testy</a>.</p>
<p>Dodatkowo przenieśliśmy się na lepszy serwer, co pozwoliło zwolnić z pracy nasz poprzedni serwer deweloperski. Na zdjęciu macierz w roli podstawki, natomiast serwer wystąpił jako nie-odkurzony-jeszcze stolik pod kawę.</p>
<p><a href="http://www.truesolutions.pl/blog/wp-content/uploads/2009/02/flux-serwer-ibm.jpg"><img src="http://www.truesolutions.pl/blog/wp-content/uploads/2009/02/flux-serwer-ibm.jpg" alt="Nasz pierwszy testowy serwer IBM" title="Nasz pierwszy testowy serwer IBM" width="400" height="496" class="size-full wp-image-169" /></a><br />
<em>Nasz pierwszy testowy serwer IBM wraz z macierzą</em></p>
<p>Oto specyfikacja tego ciężkiego zestawu (dosłownie)</p>
<ul>
<li>2x Pentium III Katmai</li>
<li>512 MB RAM</li>
<li>2x SCSI Storage Controller (Adaptec + IBM) RAID 5</li>
</ul>
<img src="http://feeds.feedburner.com/~r/TrueSolutions/~4/k9PjaaT_mW0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.truesolutions.pl/blog/trzy-tysiace-zmian-w-kodzie-plus-zdjecie-dinozaura/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Flux, czyli czego nauczył nas startup – wideo</title>
		<link>http://www.truesolutions.pl/blog/flux-czyli-czego-nauczyl-na-startup-wideo</link>
		<comments>http://www.truesolutions.pl/blog/flux-czyli-czego-nauczyl-na-startup-wideo#comments</comments>
		<pubDate>Fri, 09 Jan 2009 17:39:32 +0000</pubDate>
		<dc:creator>Jacek</dc:creator>
				<category><![CDATA[Startup]]></category>
		<category><![CDATA[flux]]></category>
		<category><![CDATA[muu.sk]]></category>
		<category><![CDATA[netcamp]]></category>
		<category><![CDATA[prezentacja]]></category>

		<guid isPermaLink="false">http://www.truesolutions.pl/blog/?p=152</guid>
		<description><![CDATA[
Na stronie szczecińskiego Netcampu pojawiły się nagrania wideo z grudniowego spotkania. Bezpośredni link do naszej prezentacji znajdziecie pod tym linkiem.

Prezentacja podsumowuje to, czego nauczyliśmy się pisząc Fluksa oraz muu.sk. Informacje w niej zawarte dla niektórych mogą okazać się dosyć oczywiste, dla innych &#8211; np. młodych wilków &#8211; mogą okazać się pomocną wskazówką. Wszystko zależy od [...]]]></description>
			<content:encoded><![CDATA[<p>
Na stronie szczecińskiego <a href="http://www.netcamp.net.pl">Netcampu</a> pojawiły się <a href="http://www.netcamp.net.pl/2009/01/09/wideo-z-netcamp-9/">nagrania wideo</a> z grudniowego spotkania. Bezpośredni link do naszej prezentacji znajdziecie pod <a href="http://www.dailymotion.pl/video/x7yxi2_netcamp-prezentacja-flux-jacek-wiec_tech">tym linkiem</a>.
</p>
<p>Prezentacja podsumowuje to, czego nauczyliśmy się pisząc <a href="http://flux.pl">Fluksa</a> oraz <a href="http://muu.sk">muu.sk</a>. Informacje w niej zawarte dla niektórych mogą okazać się dosyć oczywiste, dla innych &#8211; np. młodych wilków &#8211; mogą okazać się pomocną wskazówką. Wszystko zależy od stopnia zaawansowania wiedzy technologiczno-startupowej.</p>
<p>Udanego odbioru.</p>
<img src="http://feeds.feedburner.com/~r/TrueSolutions/~4/3xraN1Si8Ws" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.truesolutions.pl/blog/flux-czyli-czego-nauczyl-na-startup-wideo/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Spotkajmy się na KrakSpot#3 oraz Netcamp#9</title>
		<link>http://www.truesolutions.pl/blog/spotkajmy-sie-na-krakspot3-oraz-netcamp9</link>
		<comments>http://www.truesolutions.pl/blog/spotkajmy-sie-na-krakspot3-oraz-netcamp9#comments</comments>
		<pubDate>Sun, 14 Dec 2008 14:18:06 +0000</pubDate>
		<dc:creator>Jacek</dc:creator>
				<category><![CDATA[Startup]]></category>
		<category><![CDATA[flux]]></category>
		<category><![CDATA[prezentacja]]></category>
		<category><![CDATA[start-up]]></category>

		<guid isPermaLink="false">http://www.truesolutions.pl/blog/?p=134</guid>
		<description><![CDATA[
W najbliższym tygodniu odbędą się interesujące imprezy, na których będziemy mieli okazję przedstawić dwie, nieco odmienne prezentacje.


16 grudnia (wtorek) w Krakowie odbędzie się Krakspot #3, podczas którego zostanie przeprowadzony konkurs startupów. Z naszej strony zaprezentujemy Fluksa w 5-minutowej formule elevator pitch oraz zmierzymy się z opinią zaproszonych komentatorów. Warto też zapoznać się z innymi prezentacjami, [...]]]></description>
			<content:encoded><![CDATA[<p>
W najbliższym tygodniu odbędą się interesujące imprezy, na których będziemy mieli okazję przedstawić dwie, nieco odmienne prezentacje.
</p>
<p>
16 grudnia (wtorek) w Krakowie odbędzie się <a href="http://krakspot.pl">Krakspot</a> #3, podczas którego zostanie przeprowadzony <a href="http://krakspot.pl/2008/12/02/kses-na-krakspot3-konkurs-startupow/">konkurs startupów</a>. Z naszej strony zaprezentujemy <a href="http://flux.pl">Fluksa</a> w 5-minutowej formule elevator pitch oraz zmierzymy się z opinią zaproszonych komentatorów. Warto też zapoznać się z <a href="http://krakspot.pl/2008/12/13/krakspot3-oficjalna-agenda/">innymi prezentacjami</a>, które pojawią się tego wieczoru.
</p>
<p>
W najbliższą sobotę, 20 grudnia pojawimy się na <a href="http://www.netcamp.net.pl/2008/12/14/swiateczny-netcamp-9/">świątecznej edycji</a> szczecińskiej imprezy <a href="http://www.netcamp.net.pl/">Netcamp</a>. Podczas prezentacji &#8220;Flux, czyli czego nauczył nas startup&#8221; opowiemy o naszych doświadczeniach, które zdobyliśmy tworząc przez kilkanaście miesięcy <a href="http://flux.pl">naszą aplikację</a>. Skupimy się na ogólnych przemyśleniach, które można odnieść do dowolnego startupu internetowego.
</p>
<p>
Do zobaczenia w Krakowie oraz Szczecinie!</p>
<img src="http://feeds.feedburner.com/~r/TrueSolutions/~4/2VjYG9WqRVY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.truesolutions.pl/blog/spotkajmy-sie-na-krakspot3-oraz-netcamp9/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Uruchomiliśmy bloga dla projektu Flux</title>
		<link>http://www.truesolutions.pl/blog/uruchomilismy-bloga-dla-projektu-flux</link>
		<comments>http://www.truesolutions.pl/blog/uruchomilismy-bloga-dla-projektu-flux#comments</comments>
		<pubDate>Fri, 28 Nov 2008 21:30:52 +0000</pubDate>
		<dc:creator>Jacek</dc:creator>
				<category><![CDATA[Bez kategorii]]></category>
		<category><![CDATA[flux]]></category>
		<category><![CDATA[start-up]]></category>

		<guid isPermaLink="false">http://www.truesolutions.pl/blog/?p=120</guid>
		<description><![CDATA[Dla wszystkich zainteresowanych tym, co się dzieje wokół projektu Flux, uruchomiliśmy dedykowanego bloga.
Docelowo &#8211; blog który aktualnie czytasz &#8211; ma być miejscem naszych przemyśleń związanych z szeroko rozumianym biznesem internetowym. Natomiast pozostałe blogi będą precyzyjnie skupiały się przeznaczonej im tematyce.
Zapraszam do lektury!
]]></description>
			<content:encoded><![CDATA[<p>Dla wszystkich zainteresowanych tym, co się dzieje wokół projektu Flux, uruchomiliśmy dedykowanego <a href="http://blog.flux.pl">bloga</a>.</p>
<p>Docelowo &#8211; blog który aktualnie czytasz &#8211; ma być miejscem naszych przemyśleń związanych z szeroko rozumianym biznesem internetowym. Natomiast <a href="http://blog.muu.sk">pozostałe</a> <a href="http://blog.flux.pl">blogi</a> będą precyzyjnie skupiały się przeznaczonej im tematyce.</p>
<p>Zapraszam do lektury!</p>
<img src="http://feeds.feedburner.com/~r/TrueSolutions/~4/jbw8WDKI-zA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.truesolutions.pl/blog/uruchomilismy-bloga-dla-projektu-flux/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
