This is part of The Pile, a partial archive of some open source mailing lists and newsgroups.
To: modperl list <modperl@apache.org>, From: Viljo Marrandi <vilts@bbz.ee> Subject: Tips & tricks needed :) Date: Wed, 19 Dec 2001 10:50:49 +0200 Hello, We're going to make a web-site for insurance company (err, more like portal for several companies) and the problem is that ( I think ) it's going to be our biggest and most complex site we've ever done AND we're going to use some new stuff we've never used. So I'd be very happy if you can give me some points what to look at, what are real no-no's and what are go-go's. 1. We're going to switch from mysql to postgresql, because we need transactions, triggers and all other stuff that mysql doesn't support. What could be possible problems going from mysql to postgres, if any? 2. We will use Template-Toolkit and Apache/mod_perl. Problem is that 2 out of 3 people have never used TT or programmed mod_perl and OO Perl. Only I've made sites this way, they've used Embperl til now. How can I make this switch for them a little easier? I know I must spend a lot of time teaching them, but may-be there are some kinda switchover tutorials or something? 3. Authorization. Is cookie based auth most reasonable or are there some other ways too? .htaccess will not do, I think, because all data is in the same directory and authorized access/login is needed only on some parts of site. Which data should I send with cookie? Only some random key which is also stored in dbase and this key is used to find real data from dbase? (I guess I must read again this thread about cookies). 4. How is most reasonable to store(and use too) complex formulas and coefficients? Problem is that there are 4 companies and each of them has different way to calculate same thing eg. insurance for travelling, car insurance etc. Unfortunately they are all quite different, because every company uses even different things to calculate final result. So if we use different formula for every company and insurance type we end up with ~50 formulas and none understands afterwards which is which. Are there any guidelines to generalize formulas? Ok, let's say we even somehow make these formulas general enough to use, but where shall the calculation take place? Postgres stored procs or in perl code/module (i think this) or even in TT? Constans will be in db. 5. Any other things to look out when creating large site and/or running it over SSL and/or using above described configuration? P.S. I hope that in about few months I can write about this project to success stories ;-) Thanks for your attention, Viljo === To: Viljo Marrandi <vilts@bbz.ee> From: Jorge Godoy <godoy@conectiva.com> Subject: Re: Tips & tricks needed :) Date: Wed, 19 Dec 2001 09:19:05 -0200 Viljo Marrandi <vilts@bbz.ee> writes: I'm answering what I can... :-) > 3. Authorization. Is cookie based auth most reasonable or are there some > other ways too? .htaccess will not do, I think, because all data is in > the same directory and authorized access/login is needed only on some > parts of site. Which data should I send with cookie? Only some random > key which is also stored in dbase and this key is used to find real data > from dbase? (I guess I must read again this thread about cookies). First of all, why putting everything at the same place? It would be easier to maintain things if only the generic things are at the same place and specific things are in their own directories.=20 Depending on how much data you're going to store, I'd use a cookie that is a hash (e.g. MD5) to some index at the database. Don't send confidential information on them (people might use some public internet to view their information) and try not sending plain text (people might be tempted to change values).=20 > 4. How is most reasonable to store(and use too) complex formulas and > coefficients? Problem is that there are 4 companies and each of them has > different way to calculate same thing eg. insurance for travelling, car > insurance etc. Unfortunately they are all quite different, because every > company uses even different things to calculate final result. So if we > use different formula for every company and insurance type we end up > with ~50 formulas and none understands afterwards which is which. Are > there any guidelines to generalize formulas? Ok, let's say we even > somehow make these formulas general enough to use, but where shall the > calculation take place? Postgres stored procs or in perl code/module (i > think this) or even in TT? Constans will be in db. Create modules for each company. This way you'll have each company's functions on her own module. They will be differentiated by namespace. (And you can use references to select the appropriated module, the information on which company that client belongs to might be in a record at the database ;-)) By using references, your only thing to worry will be naming the same things with the same names. You should also pass values by reference.=20 Using modules will also make it possible to change formulae without worring about which of them are common to other companies or which are not common.=20 And, since you're already going to use OO Perl... ;-) === To: Viljo Marrandi <vilts@bbz.ee> From: wsheldah@lexmark.com Subject: Re: Tips & tricks needed :) Date: Wed, 19 Dec 2001 09:00:29 -0500 1. Regarding the switch to postgresql, I think that's a good choice. Just pay attention to postgresql's data types, and try to get your fields types and lengths correct the first time if possible. It doesn't completely support the ALTER TABLE command, so changing column types can be a pain, although it's still possible. The other thing is that SQL syntax might be slightly different in a few cases, though it's been too long since I used MySQL to remember any examples. Postgresql's web site has some tips for switching, I think at http://techdocs.postgresql.org. 2. Have them read some articles on the whole MVC approach, since it sounds like you'll be using that. And of course read Damian's book several times for OO perl. 4. You might put the formulas in a perl superclass, with one method per formula. Then create a subclass for each different company that has that company's algorithm. All the calling code has to worry about is which company it's dealing with when it instantiates the object; after that all the right formulas will get used automatically. This should make it easy to add more companies, too. I guess the general principle is that when you're faced with tons of complexity, try breaking it down into smaller pieces and add an abstraction layer or two, so you and the program can deal with it. Hope this helps. I'll be watching for the success story! -- Wes Sheldahl === To: wsheldah@lexmark.com From: fliptop <fliptop@peacecomputers.com> Subject: Re: Tips & tricks needed :) Date: Wed, 19 Dec 2001 09:25:48 -0500 wsheldah@lexmark.com wrote: > > 1. Regarding the switch to postgresql, I think that's a good choice. Just pay > attention to postgresql's data types, and try to get your fields types and > lengths correct the first time if possible. It doesn't completely support the > ALTER TABLE command, so changing column types can be a pain, although it's still > possible. The other thing is that SQL syntax might be slightly different in a > few cases, though it's been too long since I used MySQL to remember any > examples. Postgresql's web site has some tips for switching, I think at > http://techdocs.postgresql.org. something i'll add to that - if your new postgresql db will have foreign keys, and you previously didn't have any code written to guarantee your data's integrity in mysql, then you probably won't be able to import all your data without some massaging (unless you're sure your data's integrity is ok). i wholeheartedly second wes' statement that switching to postgresql is a good choice. === To: modperl list <modperl@apache.org> From: Jean-Michel Hiver <jhiver@mkdoc.com> Subject: Re: Tips & tricks needed :) Date: Wed, 19 Dec 2001 15:04:11 +0000 If you're developing a complex application, you'll probably want to split it in a horde of specialized modules. Few things to remember: == You will probably feel the need to use static variables (i.e. variables shared with all instances of a given class) at some point. For example if you have a singleton object you might have something like that: package Your::Singleton; use strict; use 5.6; use our $ETERNAL = undef; sub instance { my $class = shift; return $ETERNAL if (defined $ETERNAL); $ETERNAL = $class->new (@_); return $ETERNAL; } sub new { ... blah blah code ... } 1; ALWAYS reinitialize $Your::Singleton::ETERNAL on each query! mod_perl will *NOT* do it for you. You might think 'ah yeah but it would be nice if $Your::Singleton::ETERNAL could be persistent across queries...' which is sometimes desirable, but remember that if you have multiple instances of your application running on the same apache, $Your::Singleton::ETERNAL will be common to ALL of them. == Cyclic memory references are dangerous, try to avoid them as much as possible! Perl garbage collector does miserably fails in the case of cyclic refs. If you have a cycling references that keep going out of scope, they will never be garbage collected and your server might have some trouble :-) == Beware of regular expressions /o modifier! The application I'm working on has a cool feature heavily using regular expressions: automagic hyperlinking of text / html data when appropriate. I used to use the /o modifier and got a few nasty surprises (until I discovered the mod_perl guide traps page) == Other than that, more generally speaking: Always hide classes implementation with method calls! Not so long ago I did tend to write using less method calls and directly accessing object's attributes and now this is my #1 source of maintenance problem and headaches. It you think it's too slow then consider it's better to buy a bigger CPU than 3 tons of aspirin. Also avoid using packages names inside functions as much as possible, as it tends to screw inheritance. Finally my biggest piece of advice: ENFORCE a coding style. ENFORCE using english for variable, function names and comments (for example although I'm French I really can't stand code written with french variable names and comments! The Perl language is using English keywords after all. Be consistent FFS) . ENFORCE commenting what every single method does. Having said that I do naturally tend to write awful code that only I can understand, but at least everything is properly commented :) === To: Matt Sergeant <msergeant@startechgroup.co.uk> From: Tatsuhiko Miyagawa <miyagawa@edge.co.jp> Subject: Re: Tips & tricks needed :) Date: Thu, 20 Dec 2001 12:56:47 +0900 On Wed, 19 Dec 2001 16:01:22 -0000 Matt Sergeant <msergeant@startechgroup.co.uk> wrote: > Actually I was wondering about writing an Apache::Singleton class, that > works the same as Class::Singleton, but clears the singleton out on each > request (by using pnotes). Would anyone be interested in that? Like this? (using register_cleanup instead of pnotes) package Apache::Singleton; use strict; use vars qw($VERSION); $VERSION = '0.01'; use Apache; sub instance { my $class = shift; # get a reference to the _instance variable in the $class package no strict 'refs'; my $instance = "$class\::_instance"; unless (defined $$instance) { $$instance = $class->_new_instance(@_); Apache->request->register_cleanup(sub { undef $$instance }); } return $$instance; } sub _new_instance { bless {}, shift; } === To: "'Tatsuhiko Miyagawa'" <miyagawa@edge.co.jp> From: Matt Sergeant <msergeant@startechgroup.co.uk> Subject: RE: Tips & tricks needed :) Date: Thu, 20 Dec 2001 08:57:32 -0000 > -----Original Message----- > From: Tatsuhiko Miyagawa [mailto:miyagawa@edge.co.jp] > > On Wed, 19 Dec 2001 16:01:22 -0000 > Matt Sergeant <msergeant@startechgroup.co.uk> wrote: > > > Actually I was wondering about writing an Apache::Singleton > class, that > > works the same as Class::Singleton, but clears the > singleton out on each > > request (by using pnotes). Would anyone be interested in that? > > Like this? (using register_cleanup instead of pnotes) > > > package Apache::Singleton; > > use strict; > use vars qw($VERSION); > $VERSION = '0.01'; > > use Apache; > > sub instance { > my $class = shift; > > # get a reference to the _instance variable in the $class package > no strict 'refs'; > my $instance = "$class\::_instance"; > > unless (defined $$instance) { > $$instance = $class->_new_instance(@_); > Apache->request->register_cleanup(sub { undef $$instance }); > } > > return $$instance; > } > > sub _new_instance { > bless {}, shift; > } Yeah, just like that. Why don't you wrap it up and stick it on CPAN? Saves me another module :-) === To: templates list <templates@template-toolkit.org>, From: Mark Fowler <mark@twoshortplanks.com> Subject: Re: Tips & tricks needed :) Date: Thu, 20 Dec 2001 10:19:50 +0000 (GMT) (sorry to break threading but I'm getting this from multiple lists) > that IE 6 (beta at the time) considered my cookies to be third party > because I used frame-based domain redirection and by default would not > accept them. You need to include a P3P header in your HTTP header that contains a Compact Policy (CP) - a geek code of what your P3P xml privacy document contains. See http://www.w3c.org/P3P/. Some research I did seems to indicate that current implementations of IE6 will accept cookies no matter what CP you use (rather than checking it against your security settings and deciding if the CP represents a privacy policy that violates your chosen level of disclosure.) I'd really appreciate it other people could check this and confirm that IE6 is not offering any actual privacy level protection and is just discriminated against people that don't have P3P headers. My (Profero's) module for automagically converting a P3P document (the xml) into a CP (the geek-code version of that xml document) is in beta here: http://twoshortplanks.com/temp/P3P-ToCP-0.02.tar.gz Please test, break and get back to me when it doesn't work. It just follows the spec and uses XML::XPath to pull the stuff out. Later Mark. === To: Mark Fowler <mark@twoshortplanks.com> From: Mark Maunder <mark@swiftcamel.com> Subject: Re: [OT] Tips & tricks needed :) Date: Thu, 20 Dec 2001 11:04:59 +0000 Mark Fowler wrote: > I'd really appreciate it other people could check this and confirm that IE6 > is not > offering any actual privacy level protection and is just discriminated > against people that don't have P3P headers. > I tried a few header combinations before I got IE6 to send cookies in frames where one frame is an external site, so it is parsing the header, not just requiring its existence. I'm not sure if it actually looks at a users settings to determine if the policy is acceptable based on user prefs. === To: Mark Fowler <mark@twoshortplanks.com> From: Igor Sysoev <is@rambler-co.ru> Subject: Re: Tips & tricks needed :) Date: Thu, 20 Dec 2001 16:16:27 +0300 (MSK) On Thu, 20 Dec 2001, Mark Fowler wrote: > (sorry to break threading but I'm getting this from multiple lists) > > > that IE 6 (beta at the time) considered my cookies to be third party > > because I used frame-based domain redirection and by default would not > > accept them. > > You need to include a P3P header in your HTTP header that contains a > Compact Policy (CP) - a geek code of what your P3P xml privacy document > contains. See http://www.w3c.org/P3P/. > > Some research I did seems to indicate that current implementations of IE6 > will accept cookies no matter what CP you use (rather than checking it > against your security settings and deciding if the CP represents a > privacy policy that violates your chosen level of disclosure.) I'd really > appreciate it other people could check this and confirm that IE6 is not > offering any actual privacy level protection and is just discriminated > against people that don't have P3P headers. I found that IE6 require P3P header with medium and higher security settings but CP content doesn't matter - it need simply P3P: CP='anything'. Igor Sysoev === To: "Tatsuhiko Miyagawa" <miyagawa@edge.co.jp>, From: "Perrin Harkins" <perrin@elem.com> Subject: Re: Tips & tricks needed :) Date: Thu, 20 Dec 2001 11:51:30 -0500 > Like this? (using register_cleanup instead of pnotes) Better to use pnotes. I started out doing this kind of thing with register_cleanup and had problems like random segfaults. I think it was because other cleanup handlers sometimes needed access to these resources. === To: "Perrin Harkins" <perrin@elem.com> From: Tatsuhiko Miyagawa <miyagawa@edge.co.jp> Subject: Re: Tips & tricks needed :) Date: Fri, 21 Dec 2001 12:31:49 +0900 On Thu, 20 Dec 2001 11:51:30 -0500 "Perrin Harkins" <perrin@elem.com> wrote: > > Like this? (using register_cleanup instead of pnotes) > > Better to use pnotes. I started out doing this kind of thing with > register_cleanup and had problems like random segfaults. I think it was > because other cleanup handlers sometimes needed access to these resources. I'll take care of it. Thanks for the input. === To: "Perrin Harkins" <perrin@elem.com> From: Tatsuhiko Miyagawa <miyagawa@edge.co.jp> Subject: [ANNOUNCE] Apache::Singleton 0.02 (Re: Tips & tricks needed :)) Date: Sat, 22 Dec 2001 17:04:11 +0900 On Thu, 20 Dec 2001 11:51:30 -0500 "Perrin Harkins" <perrin@elem.com> wrote: > > Like this? (using register_cleanup instead of pnotes) > > Better to use pnotes. I started out doing this kind of thing with > register_cleanup and had problems like random segfaults. I think it was > because other cleanup handlers sometimes needed access to these resources. Now it uses pnotes(). Todo is to add scope configuration for each classes. The URL http://bulknews.net/lib/archives/Apache-Singleton-0.02.tar.gz has entered CPAN as file: $CPAN/authors/id/M/MI/MIYAGAWA/Apache-Singleton-0.02.tar.gz size: 1621 bytes md5: 89a86023ea672f571860e91696ff03bb 0.02 Sat Dec 22 16:58:34 JST 2001 - use pnotes instead of register_cleanup (Thanks to Perrin Harkins <perrin@elem.com>) === To: modperl@apache.org From: Tatsuhiko Miyagawa <miyagawa@edge.co.jp> Subject: [ANNOUNCE] Apache::Singleton 0.03 Date: Sat, 22 Dec 2001 22:39:03 +0900 On Sat, 22 Dec 2001 17:04:11 +0900 Tatsuhiko Miyagawa <miyagawa@edge.co.jp> wrote: > Now it uses pnotes(). Todo is to add scope configuration for each > classes. Added subclasses with own object lifetime configuration. I myself am just a little dubious about its implementation, especially for "Server" scope. Any suggestions welcome. The URL http://bulknews.net/lib/archives/Apache-Singleton-0.03.tar.gz has entered CPAN as file: $CPAN/authors/id/M/MI/MIYAGAWA/Apache-Singleton-0.03.tar.gz size: 3415 bytes md5: ba59d1e0acfd6364b045ba869c6b799c 0.03 Sat Dec 22 22:29:50 JST 2001 - Added test for multiple classes * Added Request, Process, Server subclasses NAME Apache::Singleton - Singleton class for mod_perl SYNOPSIS package Printer; use base qw(Apache::Singleton); # same: default is per Request package Printer::PerRequest; use base qw(Apache::Singleton::Request); package Printer::PerProcess; use base qw(Apache::Singleton::Process); package Printer::PerServer; use base qw(Apache::Singleton::Server); DESCRIPTION Apache::Singleton works the same as Class::Singleton, but with various object lifetime (scope). See the Class::Singleton manpage first. OBJECT LIFETIME By inheriting one of the following sublasses of Apache::Singleton, you can change the scope of your object. Request use base qw(Apache::Singleton::Request); One instance for one request. Apache::Singleton will remove intstance on each request. Implemented using mod_perl "pnotes" API. This is the default scope, so inheriting from Apache::Singleton would do the same effect. Process use base qw(Apache::Singleton::Process); One instance for one httpd process. Implemented using package global. Notice this is the same beaviour with Class::Singleton ;) Server use base qw(Apache::Singleton::Server); One instance for one server (across all httpd processes). Implemented using Cache::SharedMemoryCache (IPC). Note that multiple process cannot share blessed reference without serialization, so *One instance for one server* is just an idea. What it means is, one instance for one process, and multiple instances with shared data across one server. See t/05_server.t in this module distribution for what it exactly means. AUTHOR Original idea by Matt Sergeant <matt@sergeant.org> and Perrin Harkins <perrin@elem.com>. Code by Tatsuhiko Miyagawa <miyagawa@bulknews.net> This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. SEE ALSO the Apache::Singleton::Request manpage, the Apache::Singleton::Process manpage, the Apache::Singleton::Server manpage, the Class::Singleton manpage, the Cache::SharedMemoryCache manpage === To: <modperl@apache.org> From: brian moseley <bcm@maz.org> Subject: Re: [ANNOUNCE] Apache::Singleton 0.03 Date: Sat, 22 Dec 2001 06:04:28 -0800 (PST) On Sat, 22 Dec 2001, Tatsuhiko Miyagawa wrote: > Note that multiple process cannot share blessed reference without > serialization, so *One instance for one server* is just an idea. > What it means is, one instance for one process, and multiple > instances with shared data across one server. See t/05_server.t in > this module distribution for what it exactly means. hmm.. it looks like for the server-scoped singleton, the process-cached version will be returned by _get_instance even if the shared-memory-cached version was modified by another process since the last time _set_instance was called in the first process. is this really what you want? ===