Piotras' blog: Archive
2007-04-01 - 2007-04-30
Chicken or Egg
Posted on 2007-04-04 21:21:44 UTC.
As soon I as added midgard_config methods to create midgard tables I wanted to create new midgard_sitegroup.
( Midgard Sitegroup concept is well known but I still think I should write new mRFC. Especially now, when this class ( and simple&powerfull feature ) has new advantages. )
What should be done to create new sitegruop? Some simple method which just creates some record in database. OK, piece of cake, but to make this you need to know if logged in person is root. Hmmm... how can I check if logged in person is root if I have no such feature in core? That's clear, user accounts management should be written first. Simple...but wait. How am I to create user account in sitegroup scope if I have no sitegroup management?
It's not fun. Far from it. Writing two functionalities at the same time is not fun. To test them, you also need some simple environment. So writing two different functionalities and writing PHP bindings for them is far far from being fun.
Less fun is even if you think "it would be cool to reuse MidgardQueryBuilder for those classes". Not because one ( me for example ) may be lazy. But because the less duplicated ( or similiar code ) the less bugs should be resolved in a future. So, how can I use not MgdSchema classes with MidgardQueryBuilder if this one is highly optimized for them?
This question forced me to blessed refactoring. Review, tweak, tune, refactor, test, fix memory corruption and get the same with "new soul". And at the end MidgardDBObject class has been born from the will of having new midgard_sitegroup.
So now, class inheritance looks like this:
- GObject
- MidgardDBObject
- MidgardObject
- Any MgdSchema class
or
- GObject
- MidgardDBObject
- MidgardSitegroup
This change brings more power, so now I am even able to reflect or introspect MidgardSitegroup class object and check if such class is multilang one. I do not have to hardcode it's table or property's column name everywhere. For such features I can use introspection. Now I can say: plain and simple :)
You should stay ( still ) tuned to learn more about "how to create new sitegroup and new user accounts". But probably I will add API documentation instead of blog entry. And as I said, new mRFC will be also nice. Not for voting, but for keeping specification and idea in one place.
In other news: Bergie in his blog mentioned 'offline vs online debate'. Yes, offline is wasting the time feature if you keep in mind services like GMail or any "typical" PHP based CMS. But what about CMS or framework which has independent logic library? One which is not aware if you work offline or online? Something like Midgard :) All you need to do is to focus on GUI. I think it's worth time and work and very good to have. All in all we can also start debate: do I need battery in my laptop or in any other mobile device if electricity is almost everywhere?
midgard_sitegroup
Posted on 2007-04-12 11:42:02 UTC.
I have already created midgard database and tables so now it's high time to create new sitegroup. New , installed database has already "built-in" Midgard Administrator account. It's done automagically so nothing to worry about at this point.
Log in to Midgard framework:
$user = midgard_user::auth('admin', 'password');
You can check if logged in user is root. But it's not mandatory as midgard-core will do it for you.
if($user->is_root()) { /* do something */ }
$sg = new midgard_sitegroup();
$sg->name = "My Test Sitegroup";
$sg->realm = "My Test Sitegroup Realm";
At this point we are ready to create new sitegroup , but this sitegroup will be private one. By "private" I mean it's not public so anonymous user can not see it or use. To make it public set its 'public' property to TRUE.
$sg->public = TRUE;
Create it.
$sg->create();
Sitegrup is created. We defined it as public so you can use it for example with login screen well known from Aegir. To list all sitegroups you can use list method.
$sitegroups = midgard_sitegroup::list();
This method returns array of sitegroup names. If you are anonymous user you get only names. Guid, realm and other data are completely hidden for you. But if you are logged in as root, you can get sitegroup object using it's name.
$new_sg = new midgard_sitegroup($sitegroups[0]);
Now, you can create new group and define it as sitegroup's administrator group.
$grp = new midgard_group();
$grp->name = $sg->name ."administrators group";
Keep in mind that it's last chance to set group sitegroup! As long as you are logged in as root, you can do this.
$grp->sitegroup = $sg->id;
$created = $grp->create();
if($created) {
$sg->group = $grp->guid;
$sg->update();
}
Stay tuned ( for a while only ) to learn more about "how to create midgard person account".
midgard_user
Posted on 2007-04-12 11:59:05 UTC.
midgard_user class is something completely new in Midgard2 architecture. This is something which completely separates midgard_person object from its account. User type , login , password its kept by midgard_user for which you can assign midgard_person.
Login and password is known for everyone, but there are two new cool user features.
Person account can be active or inactive. You may have midgard_person record and its midgard_user record, but as long as person's account is inactive you can not login in.
You decide what's the way to encrypt and decrypt your password.
Create account for person.
$person = new midgard_person();
$person->username = "John";
$person->lastname = "Smith";
$person->sitegroup = 1; /* replace it with something more suitable */
$person->create();
$user = new midgard_user($person);
$user->password("mylogin", "mypassword");
Third optional argument is ommited here. But if need you can use:
- MD5 hash ( default one )
- Plain text
- SHA1 ( not yet supported )
- PAM
PAM seems to be interesting here as you can define typical Virtual Host and use PAM authentication type for selected users only.
Once account is created, you may log in.
midgard_user::auth('mylogin', 'mypassword', 'My Test Sitegroup');
Sitegroup name must be set explicitly as another argument. Unlike Midgard1 architecture. To make things even more flexible, you are able to use fourth optional argument: trusted auth type ( FALSE by default ).
midgard_user::auth('mylogin', 'mypassword', 'My Test Sitegroup', TRUE);
In this step you do not have to define your hash type. If you want to change it, use password method.
New makedist with new Makefile
Posted on 2007-04-16 20:47:47 UTC.
I just commited new Makefile for Midgard so releases, nightly builds or any other quick snapshots should be build much much easier now.
The main idea is to use custom make command and define ( and export variables ) using command line or simple helper script. In our case makedist is a helper.
makedist
It has two approaches:
define variables with default values
MIDGARD_RELEASE_VERSION=$1 MIDGARD_MAKEDIST_ROOT=$PWD MIDGARD_CORE_PREFIX="/usr/local" MIDGARD_ALL_IN_ONE_PKG="Midgard_AllinOne-${MIDGARD_RELEASE_VERSION}" MIDGARD_ALL_IN_ONE_DIR="${PWD}/${MIDGARD_ALL_IN_ONE_PKG}"
define release version
It can be set as makedist argument, but if ommited, version is determined from midgard-core configure.in.
Examples:
./makedist 1.9.1
In such case we force version number.
./makedist
And here we set every package version to this one found in :
AC_INIT([midgard-core],[1.9.0alpha1])
make
Typical Makefile, but more flexible for daily builds.
Examples:
Build midgard-core:
make midgard-core
Build midgard-php and remove files
make midgard-php
make midgard-php-clean
Build midgard-apache and Midgard_AllinOne package, clean AllinOne dir
make all-in-one-dir
make midgard-apache
make all-in-one-dir-bzip
make all-in-one-dir-clean
Not a big deal , but there is no need to write additional build scripts for different purposes. Now it should be easy to write only very simple helper script and call make with needed arguments.
midgard_php_cache
Posted on 2007-04-20 07:11:51 UTC.
That's it. I finished to write 'proof of concept` midgard_php_cache. The main approach is to reuse data which are not changed among requests or are changed very very seldom.
The basic code looks like this:
$cache = new midgard_php_cache();
This is constructor so there's nothing to elaborate about.
if(!$cache->key_exists("test_key"))
$cache->set("test_key", "test_string");
Here I check if key exists in cache , and if it's not then I add key's value. You can do 10000000 requests at this point, set method will be invoked only once. And that's the point: I do not want to create new data over and over again.
$v = $cache->get("test_key");
And finally I get my value, using ( and knowing ) the key.
I tested only strings as this is real cache's bottleneck. It must be duplicated when value should be returned. But if you consider the fact that during every request you must create plenty of variables which will or will no be used , it then seems to be a small detail.
If I could describe cache's features I would say:
- global data storage ( all data ara available per module )
- no need to select data from database or from files if you need to use the same data with every request
- integers or indexed arrays can be stored among requests without any need to initialize new data ( and thus without any need to allocate new memory for value containers )
- file contents can be reused from cache ( even with string duplication "overhead" ) reducing I/O activity to none.
- even as public data storage can be used for private ( or semi private ) data using unique key identifiers
- it's written using zend so stored data are pure, typical zend ( and thus PHP's ) value containers
midgard_php_cache VS memcache
Posted on 2007-04-20 09:57:39 UTC.
Time for a "benchmark". Let me know if you think the simple code I used is wrong.
I created two loops. 10000 steps per each.
for ($i = 0; $i < 10000; $i++) {
}
In first loop I used:
$_kv = "a".$i;
$memcache->set($_kv, $_kv);
In the second:
$_kv = "a".$i;
$memcache->get($_kv);
Next I replaced memcache object with midgard_php_cache one, and invoked almost the same methods. Simply I created 10000 arrays like this one:
"aX" => "aX"
Average time for both loops:
- memcache 0,9749
- midgard_php_cache 0,0525
Average time for only second loop:
- memcache 0,505
- midgard_php_cache 0,0369
In latter case I also printed values returned by both objects to make sure I get some data. Apache has been not restarted and I got expected values ( a1, a2, a3....) in both cases. Which looks like values has been cached among all requests.
I just wonder... why difference is so noticable?
Trying GDA on N770
Posted on 2007-04-30 08:42:18 UTC.
Last week I found Johannes Schmid blog entry about new libgda3 packages. I downloaded package's sources and recompiled it for gregale on N770. Well , I tried to recompile. These libgda3 package have some major issues:
- Can not use debian files with gda 3.0
- Sections in control files are incorrect
The latter case seems to be the most common issue I can found in debian package built for armel architecture. But maybe this is my fault. Anyway , I can not install package from file using AM. It always complain "Incompatible package" when package's section is for example lib, while it should be user/lib.
I have no idea how packages can be installed via AM directly from repositories as AM always is getting and refreshing packages list and then throws a warning "Can not refresh packages list".
Anyway , I need libreadline4 to install gda packages ( those ones I had to recompile myself ). Unfortunatelly, it seems that only bora supports libreadline4 and I need to build another packages for myself. I hope this one will be the last one. In any other case I am afraid I will have to compile plenty of packages for myself.
My big wishlist ( one wish to be exact ) is to have usable AM on N770. I have at least 4 or 5 repositories added. AM doesn't complain that repos' locaions are invalid, and I have no idea if those are good or do not trigger conflicts. Well... I should be happy anyway, as I have about 5 applications listed in AM that can be installed. None of these is the one I want.