Back up mail
Posted by Nucc
I ran into a problem, when I built my new mail server environment. I used the backup files to create the maildirs of the accounts, and I experienced my mailbox was empty in my imap client, however there were a lot of mails in it.
maildrop -V 3 -d nick@example.foo
throwed the next message:
Unable to open mailbox
despite of permissions was good.
People are disposed to exclude tmp directories from the backup files, but tmp is very important in maildir. Without tmp directory the mailbox looks empty. So modify your backup script to store the tmp directories without content to avoid the latter headaches.
My new server - part 1
Posted by Nucc
I’ve been managing a server for 3 years in a data-park. That time we had a small project that was made in Ruby on Rails (it was a pilot project). Rails deployment wasn’t so easy, however these days there are good solutions with apache and nginx specific passenger module. So we didn’t have any choice, we invested into a machine and took it to a Data park. After the work I stayed alone, and the management of the server stayed on me. Currently it’s hosting five sites with email and domain services.
It’s running Gentoo, the reason is I like specifying those features of a software that I would like to use (I don’t need graphical extension for git with x11-common package on a webserver), and other package managers usually try to find out what I should need (and usually it doesn’t succeed). The drawbacks are compile and install all the necessary packages are very-very slow, and you need to have a gcc or g++, which causes security problems.
As I mentioned, the machine has been working for 3 years, so I decided to change it (although it’s configuration would be enough, but change the whole system without any longtime stop is not so trivial). My new configuration is (thx for Imi @ Balabit!):
Intel Core2Quad Q9300 2500 Mhz- Intel DG45ID motherboard (it’s a desktop board)
- 4 x 2Gb Kingmax memory slots
- 2 x 500Gb Seagate Raid edition disk, ST3500320NS
- Chieftec BH01BBB400 box
After a lot of tests I decided it would run Debian, but exactly it’s only the base of the system. The system contains lightly separated racks, where each rack has one specified function, but share some common resources with each other. I’m going to write more about the construction of racks, by the way of the introduction they are simple chroot environments managed by Gentoo’s package manager, Portage.
You can ask me why Debian, why not Ubuntu or Gentoo. I’d like to build a thin layer, which handles only the hardware and the basic system tasks. I’d like to create a system in an hour and not in a day. I guess Ubuntu is rather a desktop instead of a server operating system. Ubuntu has the newest packages of a software, but in a server I prefer security to the rapid package building.
So, I chose software raid, I didn’t want to pay a lot of bucks for a hardware raid. I can have problems at blackout, but in a Data park it is very rare.
So my partitions:
- 150Mb /boot, ext2 (RAID1)
- 8Gb Swap | /tmp (sda|sdb)
- 5G / , XFS (RAID1)
- 453G logical partition with raid1 and lvm
Different partitions on lvm:
- /usr XFS
- /var XFS
- /backup XFS (for local backups)
- /racks XFS (storage for the racks, it’s comming later)
- /home XFS (with quota support)
I wasn’t so brave to take the / partition to a logical volume, but I hope 5G will be enough (although we know Bill Gates’ famous phrase about memory consumption)
I’ve installed the following software to the base system (without editors and other non-important stuffs):
- sshd (remote management with chroot support)
- mdadm (raid management)
- smartmontools (monitoring hard disks)
- syslog-ng (for logging)
- git (version control for /etc and rack manager software)
- backup-manager (creating backup from /etc and the racks’ rw partitions (later) with remote upload support)
- jailkit ( I’ve built a debian package in a buildd debootstrap environment because I found it only in source version, however it’s a very good tool to build and manage chroot environments)
- python (for jailkit and for my rack manager)
- aufs (for the rack environment, but I’m thinking about funionfs because aufs is a kernel module while funionfs is running in user-space by fuse. So at a crash only the fuse dies, not the whole system.)
- squashfs (for creating racks and snapshots)
The rack system will be in the next part…
Protected methods in objective-c
Posted by Nucc
In objective-c there is no language supported solution for private and protected class methods as in C++ or Java. The reason is Objective-c is only a layer on the language C which is (as it is known) not an object oriented langauge. The @protected and @private tags are only directives for the compiler to throw an error when other objects call methods in their scopes.
This compiler directives unfortunetly don’t work for methods, only for instance variables.
There are two workarounds to implement protected and private methods.
1. Let the private methods be part of the implementation file only. For instance:
-
-
Car.h:
-
-
@interface Car {
-
int tires;
-
}
-
-
-(id) init;
-
-
@end
-
-
Car.m:
-
-
@implementation Car
-
-
-(id) init
-
{
-
[super init];
-
[self setupDefaultValues];
-
return self;
-
}
-
-
// private function
-
-(void) setupDefaultValues
-
{
-
; // Custom code
-
}
-
-
@end
Using this approach your methods can be only private, which may occures problems in the future, when you try to overload a derived method, and you can not change its visibility to protected.
The compiler will throw a warning message for [self setupDefaultValues], because the compiler will be looking for this method in the @interface definition.
2. The second solution uses category pattern, which splits the header file into two parts. The main part contains the public, and the other includes the private part of your class.
In this example the Car.h is the same as in the first example, so I’ll just write the additional lines.
Car.h
----------------
@interface Car (PrivateMethods)
- (void) setupDefaultValues
@end
Car.m
----------------
@implementation Car (PrivateMethods)
- (void) setupDefaultValues
{
; // Custom code
}
@end
I haven’t found nice solution for protected methods yet. There is a convention to begin protected methods with _ mark, but I like when the compiler warns me to somebody tries to call a protected method, and I’m not forced to dig up the code for checking prefixes.
Sztaki gyorsgomb FF3.5
Posted by Nucc
Frissítettem a sztaki gyorsgomb kiegészítőt, így már működik FF3.5-ön is. További infó itt! Használjátok egészséggel!
Prototype 1.6.1-rc2
Posted by Nucc
PrototypeJS developers has announced 1.6.1-rc2 on March 27. The new release provides full IE8 compatibility, DOM functions have extended with clone method, you can store key value pairs binding to a node, and moreover better performance in bind() and DOM explorer functions.
Clone method: The javascript engines provide cloneNode() method for cloning an element of a DOM, but there were problems in IE, because IE copied only the node’s initialized version, every latter modifications (like attached event handling) lost. This prototype version calls cloneNode() method, so be careful with previous IE versions.
-
clone: function(element, deep) {
-
if (!(element = $(element))) return;
-
var clone = element.cloneNode(deep);
-
clone._prototypeUID = void 0;
-
if (deep) {
-
var descendants = Element.select(clone, ‘*’),
-
i = descendants.length;
-
while (i–) {
-
descendants[i]._prototypeUID = void 0;
-
}
-
}
-
return Element.extend(clone);
-
}
Storage: The storage engine provides capability to store key value pairs binding to a node. It’s very useful when some variables are in connection with a specified DOM element. If the element was dropped, you should remove all variables, which would become unusable. If we didn’t do this, after a while our site would eat the user’s memory, or have to clean the trashes by us.
Usage:
-
// Creating new storage
-
var storage = Element.getStorage( $(‘foobar’) );
-
-
// Attaching {foo: "bar"} to node foobar
-
$(‘foobar’).store("foo", "bar");
-
-
// Get the value
-
alert(storage.get("foo"));
-
-
// Remove node
-
$(‘foobar’).remove();
The only problem is IE8 doesn’t release the memory in my tests. I’ve tried to store 50000 strings to observe memory statistic. IE8 reserved 2 megabytes, and dropping the node didn’t realize in memory state. In FF 3.0.7 memory release works fine (it’s not strange).
New events: Events mouseenter and mouseleave are the same as mouseover and mouseout, new namings are introduced because Microsoft prefers the first pair.
Erlang
Posted by Nucc
A napokban újra előkapartam Joe Armstrong, Programming Erlang című könyvét, mert kicsit szerettem volna kizökkeni az imperatív nyelvek világából. Az Erlang, egy funkcionális nyelv, erről a fura fajról szeretnék pár sorban írni.
Az Erlanggal tavaly találkoztam, mikor is az OPM (Object Process Methodology) modellnek megfelelő felépítésű nyelvet kerestem. Az OPM egy egységes szerkezet-folyamat leírásra helyezi a hangsúlyt, az UML-ben leggyakrabban használatos szerkezeti diagrammal ellentétben. A szerkezet-folyamat alatt azt értem, hogy egy terven jelennek meg mind az állapotátmenetek, mind pedig az objektumok, melyek az átmenetekben részt vesznek. A folyamatok szemléltetésének van egy hatalmas előnye, mégpedig hogy vizuálisan is elkülönülnek egymástól a független állapotátmenetek, ezáltal a rendszert már az elejétől fogva párhuzamos folyamatokként tekinthetjük, ahol a szinkronázációs pontok (pl. shared object) azon objektumok lesznek, melyek több folyamatban is részt vesznek.
Az Erlang egy funkcionális nyelv, bár rálátásom szerint inkább gyengén funkcionálisnak nevezném. Az imperatív nyelvekben egy függvény értékét mindig az állapottér aktuális állapota határozza meg, így egy tetszőleges függvényt ugyanazokkal a paraméterekkel meghívva teljesen más eredményeket kaphatunk, ellenben a funkcionális nyelvekben szigorúan mindig ugyanazt. Ezen nyelveket inkább kutatásokra alkalmazzák, de egynéhány megjelent az iparban is, ilyen például az Erlang.
Az Erlangot mint írtam félig funkcionálisnak nevezném, ugyanis szekvenciális lefutás esetén (egy process egy szálon) funkcionális. Azonban az Erlang a párhuzamosságot célozta meg fő erényének, azon kívül, hogy gyönyörűen skálázható és igen hibatűrő. Mivel a párhuzamos programok - egész pontosan szálak - szinkronizáció során cserélnek információkat, ezért egy függvény eredményét befolyásolhatja egy másik folyamattal történő szinkronizáció eredménye. Az, hogy párhuzamos teljesen funkcionális nyelv létezhet-e, ezt inkább egy fórumbeszélgetésben boncolgatnám, de érzésem szerint nem.
A szálak futtatását a virtuális gép kezeli, így a szálak kezelése hatékonyabbá válhat, aminek megmagyarázáshoz kell írnom pár sort magáról a nyelvről.
Először is a többi nyelvben megszokott változó itt nem létezik, szerepüket konstansok váltják. Az elv a matemetikából ered, ahol ha azt állítom egy egyenletrendszer megoldásában, hogy x értéke 10, akkor bármely egyenletet tekintve az x értéke 10 lesz. Imperatív nyelveknél már nincs így, például ha veszünk egy számlálót, ami x értékét folyamatosan növeli, akkor ha a folyamatot tekintem, az x=x+1 már ellentmondásba kerülne, hisz nem tudunk olyan x-et mondani, mely kielégítené az egyenletet. Az Erlang egyenletekkel dolgozik, nem pedig értékadásokkal. Merül fel a kérdés, hogy ha nincs változó, akkor mi van helyette? A válasz erre a függvény. Az előző példában szóbahozott számláló nem más, mint egy parciálisan rekurzív függvény. Például az 1-től n-ig számláló függény az az n hosszú f(f(f(…f(0)))) függvénykompozíció, ami x > 0 intervallumon f(x+1) = f(x)+1, x = 0 esetén pedig f(0) = 0. Ekkor f(k) lesz az 1-től k-ig számláló függvényünk.
Amennyiben ennek részeredményeivel szeretnénk dolgozni, tegyük fel kiírni a képernyőre, úgy meg kell mondanunk, hogy miután megnövelte egyel az értéket, mit is tegyen az részeredménnyel. Erre szolgál a funkcionális nyelvekben használatos lambda kalkulus, ami segítségével egy függvényt paraméterként is átadhatunk, és kiértékelése majd egy általunk meghatározott ponton fog megtörténni a függvényben. Ha g(x) a kiirást végző függvény, akkor definiáljuk az f(x+1) = g(f(x)+1) egyenletet, ahol g az az identikus leképezés, mely továbbítja a függvényértéket a videókártya irányába (mondjuk elindítva egy másik folyamatot). Az új függvényünket úgy is írhatjuk, mint f(x+1, g ) := g(f(x,g) +1) ha x > 0, és f(0) = 0.
Milyen előnyökkel járhat, ha a konstansokkal dolgozunk? Párhuzamos környezetben a legnagyobb problémát az osztott változók, úgynevezett erőforrások okozzák. Biztosítanunk kell, hogy állapota mindig konzisztens maradjon, azaz például egyszerre csak egy folyamat módosítsa. Ez konstansok esetén nem okoz problémát, hiszen mindenki csak olvasni fogja. Azonban az erőforrások feladata, a szinkronizáció így nem valósulhatna meg, hisz nincs felület az információcserére.
Erlangban folyamatok létrehozása egy olcsó műveletnek számít, ezt a virtuális gép folyamatkezelőjével éri el (20000 folyamat/16ms). A folyamatok üzenetekkel kommunikálnak egymással. A folyamatokban ellenőrzőpontokat helyezünk el, melyhez egy várakozási sor, és őrfeltételek társulnak. A folyamat akkor haladhat tovább, ha a várakozási sorban lévő üzenetek valamelyikére érvényesül egy őrfeltétel. Amíg a blokkoltság fennáll, a folyamat állapota változatlan. Így ha a számlálós példát nézzük, a g függvény blokkolódjon mindaddig amíg nem kap egy üzenetet, és üzenet esetén pedig hívja meg rekurzívan önmagát úgy, hogy a számláló aktuális értékét reprezentáló konstanst növelje meg egyel. Mivel g is bárkinek üzenhet, így akár x aktuális értékét elküldheti üzenet formájában másoknak. Tehát mint látható, Erlangban az osztott változókat függvények veszik át, melyek folyamata bármikor megszakítható, és folytatható. A kommunikáció asszinkron, vagyis az üzenet elküldésével a küldő tovább fut, amíg nem terminál, vagy pedig blokkolódik.
Ez a fajta elgondolás előnye, hogy minden folyamat izoláltan fut, nem kell senkivel semmit megosztania. Ekkor viszont nem számít, hogy melyik processoron fut, továbbá az sem szükséges, hogy ugyanazon a gépen fusson ahol a többi szál. Ekkor igaz számításba kell venni a hálózati közeg sebességét (a programban szabályozhatjuk az elhelyezést), de a virtuális gépeket fürtbe szedve a folyamatokat bárhol elindíthatjuk a hálózaton, az üzenetküldést pedig a virtuális gép irányítja.
További előny, hogy imperatív nyelven megírt programoknál egy folyamat létrehozása költséges, és az operációs rendszer irányítja. Webszervereknél alkalmazzák például, hogy elindítanak 5-6 szálat, és minden, a kliens felől érkező kérést egy úgynevezett balancer valamelyik szálra tereli. Azonban problémát okozhat, ha a szerver hirtelen kap nagy terhelést. Ekkor új szálakat kéne létrehozni, ami költséges, ugyanakkor állandóan többet fenntartani pedig memóriaigényes. Erlang esetén mivel egy szál létrehozása olcsó, minden kérést külön szálra tehetünk, és akár kényelmesen újabb gépeket helyezhetünk szolgálatba bárminemű kódváltoztatás és külső eszköz (mások által megírt ütemező) nélkül.
Amennyiben érdekelnek a nyelv rejtelmei, látogass vissza később!
http://nucc.bteam.hu
OPM: http://www.slideshare.net/guest77b0cd12/object-process-methodology-presentation
Sztaki gyorsgomb
Posted by Nucc
Zolival összedobtunk egy patch-et a sztaki-szótár firefox extensionjéhez, ugyanis rohadtul zavart, hogy amennyiben egy angol szó jelentésére vagyok kíváncsi, akkor a kijelölés, jobb-gomb, listából kikeres, kattintás szekvenciális sorozatot végig kell játszanom. Erre jött az ötlet, hogy duplaklikk a szóra, és egy billentyű lenyomására már ugorjon is az ablak. Ez a billentyű a “d” lett, továbbá bevezettünk egy “f”-et is, ami levágja a többesszámot és az ing suffixot, ezzel megspórólva a hasonló szavakon való bolyongást. Amennyiben van még ötlet, írjatok!
Another day with merb and merb-assets
Posted by Nucc
I had a long morning with javascripts helpers. Two days ago, I had installed merb-0.9.0, because I have would try to probe what new features get. The main changes is the separation of merb and merb-gen. The scripts directory was removed, and we can generate models, controllers, … with merb-gen.
merb-gen project cd project merb-gen model user
It was long time, until I found this. I started to write some models, controllers, and views. And views… This cause my long-long morning. In merb, we can seperate the javascript code and the layout. It’s very important, when we have a lot of views with one common layout. Let’s look, how does it work… First, (it’s very important!!!) we need to set in config/init.rb
-
dependency "merb-assets"
It contains our javascript helpers. In merb we can set bundles, but this is another story. Next, we create the layout, it will be a very simple layout…
-
<html>
-
<head>
-
<title> Project </title>
-
<%= include_required_js %>
-
</head>
-
<body>
-
<%= catch_content :for_layout %>
-
</body>
-
</html>
include_required_js is a target, that will insert the
Let us look the Users/create view. In this view, we will use prototype framework.
-
<%- require_js "prototype" %>
-
-
<div id="content">
-
blablabla
-
</div>
And the result:
-
<html>
-
<head>
-
<title> Project </title>
-
<script src="/javascripts/prototype.js" type="text/javascript"></script>
-
</head>
-
<body>
-
<%= catch_content :for_layout %>
-
</body>
-
</html>
It was 4 hour in the morning, I downloaded the newest version from git, and the solution was dependency merb-assets. But works ![]()
Datamapper and transactions :(
Posted by Nucc
I have a new project idea, and I decided to create it by Merb and Datamapper. I’ve two model, Authentication and Profile model. The problem, DM doesn’t have transaction controlling, but it’s very necessary…
-
class Authentication < DataMapper::Base
-
property :email, :string
-
property :password, :string
-
-
belongs_to :profile
-
end
-
-
class Profile < DataMapper::Base
-
property :firstname, :string
-
property :lastname, :string
-
property :phone, :string
-
end
So we have an Authentications table, which contains email and password pairs and a pointer to a Profiles DB element. Let’s see a problem with Datamapper. There are no transaction controlling yet.
Put the case that, come a new visitor, and try to register. Add an email, password, and his profile. We create a Profile object with his params, and save it, because in Auth object we have to set saved object for profile pointer. The password not too secure, so Auth throw invalid exception, we can’t save it. There is a profile without auth. Okay, if Auth throw invalid message, delete profile. Is it solution? No.. If only you use this db, it may be a solution. But if sy create a pointer for your new profile, then database won’t delete your profile object because a DB element is pointing to it.
Okay, if we check validation before each model’s save method, it solves some problem, but good only for validation problems. Let’s see, how ActiveRecord solution. AR has transaction controlling. Every (the most) DB has transaction controlling, because it’s base. AR is capable throw Exception, when a save, or destroy method gets an error (DM only returns true or false). We do a transaction block, and if sg throw exception, we call a ROLLBACK, or if everything okay, we call COMMIT. There’s a schema:
-
def save!
-
raise "blablabla Save problem" unless save
-
true
-
end
-
-
def self.transaction(name, &block)
-
begin
-
send(START TRANSACTION)
-
yield
-
send("COMMIT")
-
rescue Exception=>e
-
send("ROLLBACK")
-
raise e
-
end
-
end
It’s only an idea, but what happens, when one transaction block contains another? If we do a commit inside another transaction, and the other transaction do a Rollback, then delete committed rows?
Merb - First steps
Posted by Nucc
I’ve read a lot of Merb, so I decided to try it. First it seems to be very poor framework, and it’s true. It’s only a skeleton unlike rails. First I tried
script/generate model User name:string email:string
and I got a pure User class without Datamapper, ActiveRecord, or other ORM. After googling I found the solution, it need to set use_orm :datamapper in dependencies.rb. For datamapper install use this:
sudo gem install datamapper sudo gem install merb_datamapper sudo gem install do_mysql
It’s okay, we generate again our model file.
script/generate model User name:string email:string
The result:
-
class User < DataMapper::Base
-
property :name, :string
-
property :email, :string
-
end
Okay, it’s nice, but how can we migrate with the database? We have a config/database.sample.yml file like in rails, edit this. It’s very nice, in Rails we have to set username, pass, database for all environment, here we can use inheritance.
:development: &defaults :adapter: mysql :database: merb_test :username: root :password: :host: localhost :test: <<: *defaults #:database: sample_test: production: <<: *defaults #:database: sample_production
Okay, it’s nice, try to migrate. … I’ve need some time, to solve this very simple problem. In rails, we have rake db:migrate, but in merb it’s not, or not ready yet. Okay, no problem, I found this solution:
In config/merb_init.rb insert this:
-
DataMapper::Persistence.auto_migrate!
It will migrating our models with database before merb server start. Let’s look an example. If we want to add a column to our User table, we only need to set another property tag, like:
-
class User < DataMapper::Base
-
property :name, :string
-
property :email, :string
-
property :message, :string
-
end
After a restart Users table looks:
desc users; +---------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +---------+-------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | name | varchar(50) | YES | | NULL | | | email | varchar(50) | YES | | NULL | | | message | varchar(50) | YES | | NULL | | +---------+-------------+------+-----+---------+----------------+
Nice. But! I’ve some problems. How can we manage, when new columns have an initialize value? How can we rename row? It’s very good for smaller projects, but what we can do, if we have an already exists database with a lot of data? It’s not trivial for me?
I shouldn’t remove migrating, but change it. I forget the numbers before the migration name, and use creation date for order them. Every migration file should has a creation date, and migration script use it for order them. It’s only an idea.
Another problem in Merb, controllers don’t get Controller suffix in class name. It seems to comfortable, but what happens, if we have a User model, and we want to use an User controller to manage our model. It’s problem. Need to use different namespaces for models and controllers, or use suffix or prefix in controllers like rails.