A Better diff Or What To Do When GNU diff Runs Out Of Memory ("diff: memory exhausted")
Monday, May 12th, 2008
Recently I ran into major problems using GNU diff. It would crash with "diff: memory exhausted" after only a few minutes trying to process the differences between a couple 4.5GB files. Even a beefy box with 9GB of RAM would run out of it in minutes.
There is a different solution, however, that is not dependent on file sizes. Enter rdiff - rsync's backbone. You can read about it here: http://en.wikipedia.org/wiki/Rsync (search for rdiff).
The upsides of rdiff are:
- with the same 4.5GB files, rdiff only ate about 66MB of RAM and scaled very well. It never crashed to date.
- it is also MUCH faster than diff.
- rdiff itself combines both diff and patch capabilities, so you can create deltas and apply them using the same program
The downsides of rdiff are:
- it's not part of standard Linux/UNIX distribution - you have to install the librsync package.
- delta files rdiff produces have a slightly different format than diff's.
- delta files are slightly larger (but not significantly enough to care).
- a slightly different approach is used when generating a delta with rdiff, which is both good and bad - 2 steps are required. The first one produces a special signature file. In the second step, a delta is created using another rdiff call (all shown below). While the 2-step process may seem annoying, it has the benefits of providing faster deltas than when using diff. In fact, you can pipe the first step into the second one without any trouble if you want, which is what I ended up doing).
Usage:
1 2 3 4 5 6 7 8 9 | $ rdiff signature ORIGINAL.txt SIGNATURE.sig $ l -h SIGNATURE.sig -rw-r--r-- 1 archon810 users 25M 2008-04-23 22:32 SIGNATURE.sig $ rdiff delta SIGNATURE.sig MODIFIED.txt DELTA.rdiff $ l -h DELTA.rdiff -rw-r--r-- 1 archon810 users 82M 2008-04-23 22:36 DELTA.rdiff |
And here's what you would do to reassemble MODIFIED.txt:
1 2 3 4 5 6 | $ rdiff patch ORIGINAL.txt DELTA.rdiff MODIFIED_REASSEMBLED.txt $ l *.txt -rw-r--r-- 1 archon810 users 4,471,493,588 2008-04-23 20:24 MODIFIED.txt -rw-r--r-- 1 archon810 users 4,471,493,588 2008-04-23 22:44 MODIFIED_REASSEMBLED.txt -rw-r--r-- 1 archon810 users 4,403,302,981 2008-04-23 20:20 ORIGINAL.txt |
Just as expected - everything matches.
Now, all of this could have been done in one go like this:
1 | rdiff signature ORIGINAL.txt | rdiff delta -- - MODIFIED.txt DELTA.rdiff |
As far as my usage of such a useful diff program, I was doing CSV dumps of certain fields from a MySQL database, like so:
1 | SELECT * FROM table WHERE some_condition='1' ORDER BY id DESC INTO OUTFILE '/home/dump/dump.csv' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'; |
and then applying rdiff to get the [quite small] daily deltas.
That's all folks!
How To Install The Latest SOAP::Lite Using Perl CPAN
Wednesday, April 30th, 2008
Apparently it's not straightforward to install SOAP::Lite, even using CPAN.
Check this out.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | cpan[1]> install SOAP::Lite
CPAN: Storable loaded ok (v2.18)
Going to read /root/.cpan/Metadata
Database was generated on Tue, 29 Apr 2008 18:29:45 GMT
CPAN: YAML loaded ok (v0.66)
Going to read /root/.cpan/build/
............................................................................DONE
Found 149 old builds, restored the state of 109
Warning: Cannot install SOAP::Lite, don't know what it is.
Try the command
i /SOAP::Lite/
to find objects with matching identifiers.
CPAN: Time::HiRes loaded ok (v1.9713) |
Huh? Okay…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | cpan[2]> i /SOAP::Lite/ Module ResourcePool::Command::SOAP::Lite::Call (MWS/ResourcePool-Resource-SOAP-Lite-1.0101.tar.gz) Module ResourcePool::Factory::SOAP::Lite (MWS/ResourcePool-Resource-SOAP-Lite-1.0101.tar.gz) Module ResourcePool::Resource::SOAP::Lite (MWS/ResourcePool-Resource-SOAP-Lite-1.0101.tar.gz) Module SOAP::Lite::Deserializer::XMLSchema1999 (MKUTTER/SOAP-Lite-0.71.04.tar.gz) Module SOAP::Lite::Deserializer::XMLSchema2001 (MKUTTER/SOAP-Lite-0.71.04.tar.gz) Module SOAP::Lite::Deserializer::XMLSchemaSOAP1_1 (MKUTTER/SOAP-Lite-0.71.04.tar.gz) Module SOAP::Lite::Deserializer::XMLSchemaSOAP1_2 (MKUTTER/SOAP-Lite-0.71.04.tar.gz) Module SOAP::Lite::InstanceExporter (SMEISNER/SOAP-Lite-InstanceExporter-0.02.tar.gz) Module SOAP::Lite::Packager (MKUTTER/SOAP-Lite-0.71.04.tar.gz) Module SOAP::Lite::Simple (LLAP/SOAP-Lite-Simple-1.9.tar.gz) Module SOAP::Lite::Simple::DotNet (LLAP/SOAP-Lite-Simple-1.4.tar.gz) Module SOAP::Lite::Simple::Real (LLAP/SOAP-Lite-Simple-1.4.tar.gz) Module SOAP::Lite::Utility (BRYCE/SOAP-Lite-Utility-0.01.tar.gz) Module SOAP::Lite::Utils (MKUTTER/SOAP-Lite-0.71.04.tar.gz) 14 items found |
Wtf? Let's try something else.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | cpan[8]> i /SOAP.*Lite/ Distribution BRYCE/SOAP-Lite-Utility-0.01.tar.gz Distribution BYRNE/SOAP/SOAP-Lite-0.60a.tar.gz Distribution DYACOB/SOAP-Lite-ActiveWorks-0.10.tar.gz Distribution DYACOB/SOAP-Lite-SmartProxy-0.11.tar.gz Distribution LLAP/SOAP-Lite-Simple-1.4.tar.gz Distribution LLAP/SOAP-Lite-Simple-1.9.tar.gz Distribution MKUTTER/SOAP-Lite-0.71.04.tar.gz Distribution MWS/ResourcePool-Resource-SOAP-Lite-1.0101.tar.gz Distribution SMEISNER/SOAP-Lite-InstanceExporter-0.02.tar.gz Module Catalyst::Action::SOAP::DocumentLiteral (DRUOSO/Catalyst-Controller-SOAP-0.8.tar.gz) Module Catalyst::Action::SOAP::DocumentLiteralWrapped (DRUOSO/Catalyst-Controller-SOAP-0.8.tar.gz) Module Catalyst::Action::SOAP::RPCLiteral (DRUOSO/Catalyst-Controller-SOAP-0.8.tar.gz) Module Catalyst::Controller::SOAP::DocumentLiteralWrapped (DRUOSO/Catalyst-Controller-SOAP-0.8.tar.gz) Module Net::DRI::Transport::HTTP::SOAPLite (PMEVZEK/Net-DRI-0.85.tar.gz) Module ResourcePool::Command::SOAP::Lite::Call (MWS/ResourcePool-Resource-SOAP-Lite-1.0101.tar.gz) Module ResourcePool::Factory::SOAP::Lite (MWS/ResourcePool-Resource-SOAP-Lite-1.0101.tar.gz) Module ResourcePool::Resource::SOAP::Lite (MWS/ResourcePool-Resource-SOAP-Lite-1.0101.tar.gz) Module = SOAP::Lite::Deserializer::XMLSchema1999 (MKUTTER/SOAP-Lite-0.71.04.tar.gz) Module = SOAP::Lite::Deserializer::XMLSchema2001 (MKUTTER/SOAP-Lite-0.71.04.tar.gz) Module = SOAP::Lite::Deserializer::XMLSchemaSOAP1_1 (MKUTTER/SOAP-Lite-0.71.04.tar.gz) Module = SOAP::Lite::Deserializer::XMLSchemaSOAP1_2 (MKUTTER/SOAP-Lite-0.71.04.tar.gz) Module SOAP::Lite::InstanceExporter (SMEISNER/SOAP-Lite-InstanceExporter-0.02.tar.gz) Module = SOAP::Lite::Packager (MKUTTER/SOAP-Lite-0.71.04.tar.gz) Module SOAP::Lite::Simple (LLAP/SOAP-Lite-Simple-1.9.tar.gz) Module SOAP::Lite::Simple::DotNet (LLAP/SOAP-Lite-Simple-1.4.tar.gz) Module SOAP::Lite::Simple::Real (LLAP/SOAP-Lite-Simple-1.4.tar.gz) Module SOAP::Lite::Utility (BRYCE/SOAP-Lite-Utility-0.01.tar.gz) Module = SOAP::Lite::Utils (MKUTTER/SOAP-Lite-0.71.04.tar.gz) 28 items found |
Aha! It's hiding under a Distribution. Tricky, tricky.
1 2 | cpan install MKUTTER/SOAP-Lite-0.71.04.tar.gz |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | CPAN.pm: Going to build M/MK/MKUTTER/SOAP-Lite-0.71.04.tar.gz
We are about to install SOAP::Lite and for your convenience will provide
you with list of modules and prerequisites, so you'll be able to choose
only modules you need for your configuration.
XMLRPC::Lite, UDDI::Lite, and XML::Parser::Lite are included by default.
Installed transports can be used for both SOAP::Lite and XMLRPC::Lite.
Press to see the detailed list.
Feature Prerequisites Install?
----------------------------- ---------------------------- --------
Core Package [*] Scalar::Util always
[*] Test::More
[*] URI
[*] MIME::Base64
[*] version
[*] XML::Parser (v2.23)
Client HTTP support [*] LWP::UserAgent always
Client HTTPS support [*] Crypt::SSLeay [ yes ]
Client SMTP/sendmail support [ ] MIME::Lite [ no ]
Client FTP support [*] IO::File [ yes ]
[*] Net::FTP
Standalone HTTP server [*] HTTP::Daemon [ yes ]
Apache/mod_perl server [ ] Apache [ no ]
FastCGI server [ ] FCGI [ no ]
POP3 server [*] MIME::Parser [ yes ]
[*] Net::POP3
IO server [*] IO::File [ yes ]
MQ transport support [ ] MQSeries [ no ]
JABBER transport support [ ] Net::Jabber [ no ]
MIME messages [*] MIME::Parser [ yes ]
DIME messages [*] IO::Scalar (v2.105) [ no ]
[ ] DIME::Tools (v0.03)
[ ] Data::UUID (v0.11)
SSL Support for TCP Transport [ ] IO::Socket::SSL [ no ]
Compression support for HTTP [*] Compress::Zlib [ yes ]
MIME interoperability w/ Axis [ ] MIME::Parser (v6.106) [ no ]
--- An asterix '[*]' indicates if the module is currently installed.
Do you want to proceed with this configuration? [yes]
Checking if your kit is complete...
Looks good
Writing Makefile for SOAP::Lite
cp lib/SOAP/Packager.pm blib/lib/SOAP/Packager.pm
cp lib/XML/Parser/Lite.pm blib/lib/XML/Parser/Lite.pm
...
Writing /usr/lib/perl5/site_perl/5.10.0/i686-linux/auto/SOAP/Lite/.packlist
Appending installation info to /usr/lib/perl5/5.10.0/i686-linux/perllocal.pod
MKUTTER/SOAP-Lite-0.71.04.tar.gz
/usr/bin/make install -- OK |
The latest version of SOAP::Lite is installed, time to pat yourself on the back and write some code to actually use it.
How Do I Get Both The Return Value And Text In Perl? Backticks vs. System() (Perl 5.10)
Tuesday, April 29th, 2008
I'm sure most Perl coders have to face this annoying problem at one point or another: how do you consistently get the return value out of a system call, be at executed via backticks or system()? Backticks return the output of the program with no error code in sight, while system() returns the error code but prints the output instead of putting it into a variable.
The best solution I could find to this problem to date was posted at http://www.perlmonks.org/?node_id=19119 and involved opening a piped filehandle. It worked quite well but always felt like a hack (which it was). Having used the new Perl 5.10 for a few months, I was shocked today to find this new variable that I've been dreaming about for years:
1 | ${^CHILD_ERROR_NATIVE} |
This variable gives the native status returned by the last pipe close, backtick command, successful call to wait() or waitpid(), or from the system() operator. See perlrun for details. (Contributed by Gisle Aas.)
http://search.cpan.org/dist/perl-5.10.0/pod/perl5100delta.pod#New_internal_variables
I've just tested it and it works as described. Finally!.. what else can I say?
Do NOT Use This Perl Module: Passwd::Unix
Tuesday, April 22nd, 2008
Updated: April 29th, 2008
Update: The author of the module contacted me the same day and promised to fix it in the next version. Version 0.40 was indeed on cpan as promised, but I haven't tested it yet.
Passwd::Unix will corrupt your /etc/shadow file and rearrange login names and their corresponding password hashes.
The current version of Passwd::Unix corrupted my /etc/shadow upon only
calling the passwd() function. Immediately users started to report not
being able to login.
After examining the situation, I found that Passwd::Unix rearranges all
users in /etc/shadow in some way, but it only does it to the
usernames, and not the password hashes. Thus, you will get corrupted accounts. Moreover,
users are now able to login to one OTHER account, not their own,
depending on how the usernames got shuffled.
Thankfully, I had a recent backup but I definitely don’t want anyone
else to suffer.
I’m using perl 5.10, SUSE 10.3. If it’s incompatible with SUSE, it needs
to say so and exit.
I've filed the bug here: http://rt.cpan.org/Public/Bug/Display.html?id=35323.
You have been warned.
My MySQL Conference Schedule
Sunday, April 13th, 2008
Were there too many "my"'s in that title? Anyway… this week's MySQL conference is promising to be really busy and exciting. I can't wait to finally be there and experience it in all its glory. Thanks to the O'Reilly personal conference planner and scheduler and the advice of my fellow conference goers, I was able to easily (not really) pick out the speeches I am most interested in attending.
Here goes (my pass doesn't include Monday
):
Tuesday
8:30am Tuesday, 04/15/2008
Keynote Ballroom E
Mårten Mickos (MySQL)
In his annual State of MySQL keynote, Marten discusses the current and future role of MySQL in the modern online world. The presentation also covers the acquisition by Sun of MySQL, the role open source is playing for users and customers all over the planet, and what the visions for the future are. Read more.
9:05am Tuesday, 04/15/2008
Open Source: The Heart of the Network Economy
Keynote Ballroom E
Jonathan Schwartz (Sun Microsystems)
Free software and open communities are the lifeblood of network innovation. Sun Microsystems CEO Jonathan Schwartz will highlight the rising open source tide and how Sun's recently announced acquisition of MySQL furthers free software as a platform for the web economy. Read more.
9:40am Tuesday, 04/15/2008
A Head in the Cloud - The Power of Infrastructure as a Service
Keynote Ballroom E
Werner Vogels (Amazon.com)
There are many challenges when building a reliable, flexible architecture that can manage unpredictable behaviors of today's internet business. This presentation will review some of the lessons learned from building one of the world's largest distributed systems; Amazon.com. Read more.
10:50am Tuesday, 04/15/2008
Performance Guide for MySQL Cluster
MySQL Cluster and High Availability, Performance Tuning and Benchmarks Ballroom D
Mikael Ronstrom (MySQL)
Learn about all the tricks required to make MySQL Cluster high performance. This includes using real-time scheduling, batching in all its form, cluster interconnects, and locking threads to CPUs. Read more.
11:55am Tuesday, 04/15/2008
The Future of MySQL: What You Need to Know About What's Coming
Architecture and Technology, General Ballroom B
Robin Schumacher (Sun/MySQL), Rob Young (Sun/MySQL)
What enhancements can you expect in the MySQL Server in the next few years? What new tools, services, and software is MySQL going to deliver this year and next to help you deploy and maintain MySQL applications? This session will let you in on all the plans MySQL has for the server, the Enterprise Monitor, the upcoming Load Balancer and Query Analyzer, management tools, and more. Read more.
2:00pm Tuesday, 04/15/2008
InnoDB: Status, Architecture, and New Features
Architecture and Technology Ballroom F
Heikki Tuuri (Innobase / Oracle Corp.), Ken Jacobs (Oracle / Innobase)
Ken Jacobs and Heikki Tuuri will describe the InnoDB architecture in depth, and discuss the new powerful performance-enhancing capabilities in InnoDB. Read more.
3:05pm Tuesday, 04/15/2008
Investigating Innodb Scalability Limits
Performance Tuning and Benchmarks Ballroom F
Peter Zaitsev (MySQL Performance Blog), Vadim Tkachenko (MySQLPerformanceBlog.com)
You may have heard Innodb has limited scalability with multiple CPUs and some of these were fixed in recent MySQL 5.0 versions. In this presentations we will look into which problems are fixed. Read more.
4:25pm Tuesday, 04/15/2008
Disaster is Inevitable—Are You Prepared?
Security and Database Administration Ballroom B
Farhan Mashraqi (Fotolog)
What’s the worst disaster you expect to happen? What can you do to better prepare for the disaster? Join us in this heart-racing, real-life inspired presentation for answers to these questions and more. Read more.
5:15pm Tuesday, 04/15/2008
Mitigating Replication Latency in a Distributed Application Environment
Architecture and Technology, Business and Case Studies, Replication and Scale-Out Ballroom E
Jeff Freund (Clickability)
Master-Master replication provides high availability and serviceability for the applications. Publishing web sites is a read-intensive operation, and the combination of Master-Slave replication with an application layer that intelligently splits database read and write operations allows for rapid scale out. Hear how Clickability solves issues for both environments. Read more.
Wednesday
8:30am Wednesday, 04/16/2008
Copyright Regime vs. Civil Liberties
Keynote Ballroom E
Rick Falkvinge (Swedish Pirate Party)
Rick Falkvinge, founder of the Swedish Pirate Party, talks about the rise and success of pirates and why pirates are necessary in today's politics. He'll also outline the next steps in the pirates' strategy to change global copyright laws. Read more.
9:15am Wednesday, 04/16/2008
Keynote Ballroom E
John Allspaw (Flickr (Yahoo!)), Jeff Rothschild (Facebook.com), Monty Taylor (MySQL), Domas Mituzas (MySQL), Paul Tuckfield (YouTube)
This lively panel discussion keynote will address the challenges large, modern web properties face in scaling MySQL. Panelists from Facebook, YouTube, and Flickr pair up with MySQL engineers in discussing the current and future problem domain and possible solutions. Read more.
10:00am Wednesday, 04/16/2008
Faster, Greener, Cheaper: Why Every MySQL Database Server Will One Day Have a SQL Chip
Keynote Ballroom E
Raj Cherabuddi (Kickfire)
The history of computing is full of algorithms such as graphics processing that are fine-tuned in general purpose CPUs over decades. Only when they are finally ported to dedicated hardware are tremendous improvements in speed, cost, and power realized. Raj Cherabuddi explains how a new SQL chip will revolutionize today’s database query processing. Read more.
10:50am Wednesday, 04/16/2008
Portable Scale-out Benchmarks for MySQL
Architecture and Technology, Performance Tuning and Benchmarks, Replication and Scale-Out Ballroom D
Robert Hodges (Continuent.com)
This talk presents new open source tools that allow users to set up and run database scale-out benchmarks easily. Hodges illustrates with benchmark results from your favorite MySQL configurations. Read more.
11:55am Wednesday, 04/16/2008
Applied Partitioning and Scaling Your Database System
General Ballroom D
Phil Hildebrand (thePlatform)
Take advantage of MySQL partitioning to allow your database applications to scale in both size and performance. A practical look at applying partitioning to OLTP database systems. Read more.
2:00pm Wednesday, 04/16/2008
Architecture of Maria: A New Storage Engine with a Transactional Design
Architecture and Technology, Performance Tuning and Benchmarks Ballroom E
Michael Widenius (MySQL)
A deep tour into the design of Maria, a new MVCC storage engine for MySQL from the original authors of MySQL that is designed to support transactions and automatic recovery. Read more.
3:05pm Wednesday, 04/16/2008
An Introduction to BLOB Streaming for MySQL Project
Java, Storage Engine Development and Optimization Ballroom A
Paul McCullagh (PrimeBase Technologies GmbH)
This session explains how the BLOB Streaming engine solves the problems involved in storing pictures, films, MP3 files, and other binary and text objects (BLOBs) in the database. Read more.
4:25pm Wednesday, 04/16/2008
Benchmarking and Monitoring: Tools of the Trade (Part I)
Performance Tuning and Benchmarks Ballroom D
Tom Hanlon (MySQL)
Benchmarking and Profiling are extrememly important and a large array of tools exist for the job. Join Tom Hanlon for a tour of the current landscape. Demos of each tool wil be shown. Read more.
5:15pm Wednesday, 04/16/2008
Benchmarking and Monitoring: Tools of the Trade (Part II)
Performance Tuning and Benchmarks, Security and Database Administration Ballroom D
Tom Hanlon (MySQL)
Join us for a presentation of the wonderful world of benchmarks and monitoring tools. Here you will learn what is available, how each tool works, and a demonstration using each tool against a running database from a veteran MySQL expert. Read more.
8:30pm Wednesday, 04/16/2008
Event Ballroom F
Have a drink, mingle with fellow conference participants, and enter our raffle to win great prizes, including a a Sony PS3! Sponsored by Sun Microsystems. Read more.
Thursday
8:30am Thursday, 04/17/2008
Keynote Ballroom E
Dick Hardt (Sxip Identity Corporation)
Much of the data in a database is about people. Identity 2.0 technologies will lower the friction for people to provide and easily move data about themselves online. This fast paced keynote will offer a background on Identity 2.0, discuss current roadblocks and future opportunities, and explore the potential impacts these will have on databases. Read more.
9:15am Thursday, 04/17/2008
A Match Made in Heaven? The Social Graph and the Database
Keynote Ballroom E
Jeff Rothschild (Facebook.com)
Social applications integrate information about many different facets of people’s lives. Join us as Jeff Rothschild from Facebook looks at the power of the social graph, how it can increase the utility and adoption of applications, and its implications on storage architectures. Read more.
10:50am Thursday, 04/17/2008
MySQL Proxy, the Friendly Man in the Middle
Architecture and Technology Ballroom F
Jan Kneschke (MySQL), Jimmy Guerrero (Sun-MySQL)
MySQL Proxy is a tool to route, rewrite, handle, and block queries on the MySQL Protocol level. Load Balancing, Query Replay, Online Query Rewrites, and more with a grain of scripting. Read more.
11:55am Thursday, 04/17/2008
Sphinx: High Performance Full Text Search for MySQL
General Ballroom C
Andrew Aksyonoff (Sphinx Technologies), Peter Zaitsev (MySQL Performance Blog)
Sphinx is an open source full-text search engine designed for indexing databases and integrated especially well with MySQL. We'll talk about its features, capabilities, and real-world applications. Read more.
2:00pm Thursday, 04/17/2008
Top 20 DB Design Tips Every Architect Needs to Know
Architecture and Technology, Data Warehousing and Business Intelligence, Security and Database Administration Ballroom B
Ronald Bradford (Primebase Technologies)
Each database product has strengths and weaknesses. Having chosen MySQL as your database product, leverage the strengths of the product to maximize design and performance. Learn the things to avoid. Read more.
2:50pm Thursday, 04/17/2008
Architecture and Technology, Java, Ruby and MySQL Ballroom G
Farhan Mashraqi (Fotolog)
Lucene is a high performance, scalable, full-text search engine library that allows you to add search to any application. This presentation shows you how you can use Lucene within your environment. Read more.
3:50pm Thursday, 04/17/2008
The Science and Fiction of Petascale Analytics
Keynote Ballroom E
Jacek Becla (Stanford Linear Accelerator Center)
Scientists are trying to understand dark matter, discover distant galaxies, hunt for the Higgs boson, detect asteroids, and take movies of molecules. Their science is fascinating but their analysis requirements may seem like science fiction. Few have experienced the reality of petascale analytics so far, but everybody, including you, will face it tomorrow. Are we ready? Read more.
4:35pm Thursday, 04/17/2008
Event Ballroom E
Take the opportunity to network one last time at this closing event. Say thank you and exchange contact information until next year. Read more.
Phew. I think I've picked out the most interesting topics. I'm excited to see Peter, Farhan, Ron, Paul, Jan, and everyone else. I hope I didn't skip anything interesting…

(No Ratings Yet)
beer planet is Artem Russakovskii's blog. Artem is a software engineer at