Re: [ANNOUNCE] Apache::SOAP 0.47 (mod_soap)

2001-02-24 Thread Adi Fairbank

Paul,

I've done some work on Keith Brown's SOAP module, and I like its design, but one
thing I noticed is that it is slow.  Even under mod_perl, it can take up to 1
second(!) to serialize a large data structure.  I believe the reason is that it
makes method calls for every element in the Perl data structure, and method
calls in Perl are inefficient due to the symbol table lookups and @ISA
checking.  So the larger the data structure the worse the performance.  (I added
array support to it and tested an array of 200 values, which took ~1 sec to
serialize under mod_perl).

I'd be interested in speed comparisons between SOAP and SOAP::Lite.  I've looked
at your code, but not actually run it.  It doesn't look like you use recursive
method calls the way Keith does.  Have you done any benchmarks on large data
structure serialization?  I assume deserialization performance will be roughly
equivalent for SOAP vs. SOAP::Lite since they both use XML::Parser.  I read the
PERFORMANCE section on base64 encoding, but it didn't mention serialization
speed.

I am currently using SOAP, because I like the DM design, but I would switch to
SOAP::Lite if its serialization speed is significantly better.

Cheers,
-Adi

Paul Kulchenko wrote:
 
  you are dedicated to supporting the full SOAP API (not sure what
  SOAP::Lite leaves out).
 First thing I did seven months ago was my email to Keith Brown
 (author of DM's SOAP/Perl module) about possible ways for cooperation
 and I'v been told that he's willing to, but design of his module
 should be consistent with other DM's implementations and he has no
 plans to change it. There was no easy way to combine our efforts and
 I came up with another implementation. Don't want to praise myself,
 but feature set seems to be pretty comparable with other toolkits. I
 took ::Lite, just because SOAP namespace was already taken. It does
 much more than you can expect from something with suffix Lite. "Lite
 suffix reflects number of calories you should spend using this
 module".





Re: [ANNOUNCE] Apache::SOAP 0.47 (mod_soap)

2001-02-24 Thread Paul Kulchenko

Hi, Adi!

 performance.  (I added
 array support to it and tested an array of 200 values, which took
 ~1 sec to serialize under mod_perl).
I see I wasn't the only person who starts with adding Array support
to it and I even made my copy of it SOAP1.1 compliant, but then Keith
came with his compliant version.

As for performance, I tried and got similar results on my machine. I
don't know your environment, so I included all my scripts, so you may
try them on your machine and let us know.

Anyway, here is my results (win98):

Benchmark: timing 10 iterations of 100x100, 1x100...
   100x100: 10 wallclock secs ( 9.72 usr +  0.00 sys =  9.72 CPU) @ 
1.03/s (n=10)
 1x100:  9 wallclock secs ( 9.17 usr +  0.00 sys =  9.17 CPU) @ 
1.09/s (n=10)

So, time is about 1 sec for roundtrip to mod_perl (serialization -
deserialization - invocation - serialization - deserialization)

Time for serialization only is different:

Benchmark: timing 100 iterations of (1)x200, (1x100)x200...
   (1)x200: 23 wallclock secs (23.34 usr +  0.00 sys = 23.34 CPU) @ 
4.28/s (n=100)
(1x100)x200: 25 wallclock secs (24.99 usr +  0.00 sys = 24.99 CPU) @ 
4.00/s (n=100)

So, about 4 times bette. Same script on Linux (serialization only):

Benchmark: timing 100 iterations of (1)x200, (1x100)x200...
   (1)x200:  5 wallclock secs ( 5.53 usr +  0.01 sys =  5.54 CPU)
(1x100)x200:  6 wallclock secs ( 5.79 usr +  0.02 sys =  5.81 CPU)

About 18 times a second.

Try these scripts in your environment for better results.

# Serialization 

use SOAP::Lite;

use Benchmark;

$s = SOAP::Serializer-new;

$array1 = [(1) x 200];
$array100 = [(1x100) x 200];

Benchmark::timethese(100, {
  '(1)x200' = sub { $s-method(a = $array1) },
  '(1x100)x200' = sub { $s-method(a = $array100) },
})

# mod_perl 

use SOAP::Lite;

$s = SOAP::Lite
  - uri('http://www.soaplite.com/My/Parameters')
  - proxy('http://localhost/soap')
;

use Benchmark;

$s-echo; # ignore first call, don't give a start to the first one

$array1 = [(1) x 200];
$array100 = [(1 x 100) x 200];

Benchmark::timethese(10, {
  '1x100' = sub { $s-echo($array1) },
  '100x100' = sub { $s-echo($array100) },
})

# 

 second(!) to serialize a large data structure.  I believe the
 reason is that it
 makes method calls for every element in the Perl data structure,
 and method
 calls in Perl are inefficient due to the symbol table lookups and
 @ISA
 checking.  So the larger the data structure the worse the
That's right, but first Perl caches calls that involve inheritance
and second, I use the same scheme, because arrays can have everything
inside and I need to call serialization function for every element in
array. I did profiling for several versions and did some
improvements, but there is no obvious stopper.

 I am currently using SOAP, because I like the DM design, but I
 would switch to
 SOAP::Lite if its serialization speed is significantly better.
I'd like to know your results, with your Array implementation. Thank
you.

Best wishes, Paul.

--- Adi Fairbank [EMAIL PROTECTED] wrote:
 Paul,
 
 I've done some work on Keith Brown's SOAP module, and I like its
 design, but one
 thing I noticed is that it is slow.  Even under mod_perl, it can
 take up to 1
 second(!) to serialize a large data structure.  I believe the
 reason is that it
 makes method calls for every element in the Perl data structure,
 and method
 calls in Perl are inefficient due to the symbol table lookups and
 @ISA
 checking.  So the larger the data structure the worse the
 performance.  (I added
 array support to it and tested an array of 200 values, which took
 ~1 sec to serialize under mod_perl).
 
 I'd be interested in speed comparisons between SOAP and SOAP::Lite.
  I've looked
 at your code, but not actually run it.  It doesn't look like you
 use recursive
 method calls the way Keith does.  Have you done any benchmarks on
 large data
 structure serialization?  I assume deserialization performance will
 be roughly
 equivalent for SOAP vs. SOAP::Lite since they both use XML::Parser.
  I read the
 PERFORMANCE section on base64 encoding, but it didn't mention
 serialization
 speed.
 
 I am currently using SOAP, because I like the DM design, but I
 would switch to
 SOAP::Lite if its serialization speed is significantly better.
 
 Cheers,
 -Adi
 
 Paul Kulchenko wrote:
  
   you are dedicated to supporting the full SOAP API (not sure
 what
   SOAP::Lite leaves out).
  First thing I did seven months ago was my email to Keith Brown
  (author of DM's SOAP/Perl module) about possible ways for
 cooperation
  and I'v been told that he's willing to, but design of his module
  should be consistent with other DM's implementations and he has
 no
  plans to change it. There was no easy way to combine our efforts
 and
  I came up with another implementation. Don't want to praise
 myself,
  but feature set seems 

Re: [ANNOUNCE] Apache::SOAP 0.47 (mod_soap)

2001-02-24 Thread Gunther Birznieks

At 05:14 PM 2/24/2001 -0800, Paul Kulchenko wrote:
That's right, but first Perl caches calls that involve inheritance
and second, I use the same scheme, because arrays can have everything
inside and I need to call serialization function for every element in
array. I did profiling for several versions and did some
improvements, but there is no obvious stopper.

Is there any way to add an interface to basically provide serialization and 
deserialization hints? My experience in the way we use SOAP is that there 
are only a few core objects that really require SOAP and the rest can be on 
the front-end.

Maybe using a CORBA-like IDL config? Thus, I could give a strong hint to 
SOAP::Lite that a particular array only contained one type of object...

In the stuff I've been doing over the last year, I've always wrote my own 
serializer/deserializer from scratch because I wanted it to be fast and 
have control over optimization rather than using the libraries that already 
exist out there.

Later,
Gunther




Re: [ANNOUNCE] Apache::SOAP 0.47 (mod_soap)

2001-02-24 Thread Paul Kulchenko

Hi, Gunther!

 Is there any way to add an interface to basically provide
 serialization and 
 deserialization hints? My experience in the way we use SOAP is that
There is no way to ptovide hints, but you have several options to
alter serializer/deserializer and use all other infrastructure. For
example, you may override serializer completely from scratch and then
register it with:

my $soap = SOAP::Lite-serializer(My::Serializer-new)-...

Or you may inherit your own serializer and specify it in the same
way. The same thing is true about deserializer and about server side
(these methods are available there also).

I did some tests with overriding serializers and truly results are
surprised me at least a little bit. Script is below. Results:

o - (1)x200: 23 wallclock secs (23.68 usr +  0.00 sys = 23.68 CPU) @ 
4.22/s (n=100)
o - (1x100)x200: 25 wallclock secs (24.99 usr +  0.00 sys = 24.99
CPU) @  4.00/s (n=100)

a - (1)x200: 15 wallclock secs (15.33 usr +  0.00 sys = 15.33 CPU) @ 
6.52/s (n=100)
a - (1x100)x200: 16 wallclock secs (16.14 usr +  0.00 sys = 16.14
CPU) @  6.20/s (n=100)

t - (1)x200:  6 wallclock secs ( 5.11 usr +  0.00 sys =  5.11 CPU) @
19.57/s (n=100)
t - (1x100)x200:  6 wallclock secs ( 6.15 usr +  0.00 sys =  6.15
CPU) @ 16.26/s (n=100)

x - (1)x200:  2 wallclock secs ( 2.08 usr +  0.00 sys =  2.08 CPU) @
48.08/s (n=100)
x - (1x100)x200:  3 wallclock secs ( 3.19 usr +  0.00 sys =  3.19
CPU) @ 31.35/s (n=100)

First is default serializer. 

Second makes serialization only for first element of array and then
duplicates the results, emulating procedure for one type for all
elements. 50% better

Third generates ready to use xml and provides it as the result (you
may provide xml fragments during serialization) using serializer's
tag function. Almost 5 times better comparing to default.

Forth generates xml with by-hand coding. Almost 10 times better than
default. Everithing else is generated by serializer, so you can
insert your fragment seamlessly.

It's definitely something to think about. I'll take a closer look,
but it shows that having some information about data structure you
may significantly speed up this process. You may alter serialization
depending on user-defined class, depending on Object class, depending
on ref type (array, hash, scalar), etc., so you have almost full
control on serializer behavior. Create you own, override what you
need, register it and you're done.

Here is the script

# -- -- -- -- -- -- -- -- -- -- --

use SOAP::Lite;

use Benchmark;

$s = SOAP::Serializer-new;
$a = My::Serializer::Array-new;
$x = My::Serializer::XML-new;
$t = My::Serializer::XMLtag-new;

$array1 = [(1) x 200];
$array100 = [(1x100) x 200];

Benchmark::timethese(100, {
  'o - (1)x200' = sub { $s-method(a = $array1) },
  'o - (1x100)x200' = sub { $s-method(a = $array100) },
  'a - (1)x200' = sub { $a-method(a = $array1) },
  'a - (1x100)x200' = sub { $a-method(a = $array100) },
  'x - (1)x200' = sub { $x-method(a = $array1) },
  'x - (1x100)x200' = sub { $x-method(a = $array100) },
  't - (1)x200' = sub { $t-method(a = $array1) },
  't - (1x100)x200' = sub { $t-method(a = $array100) },
});

BEGIN {

  package My::Serializer::Array;

  @My::Serializer::Array::ISA = 'SOAP::Serializer';

  sub encode_array {
my($self, $array, $name, $type, $attr) = @_;
my $items = 'item'; 

my @items = ($self-encode_object($array-[0], $items)) x
@$array;

return [$name || '~C:Array', {%{$attr || {}}, '~C:arrayType' =
$arraytype, 'xsi:type' = SOAP::Utils::qualify('~C' = $type)},
[@items], $self-gen_id($array)];
  }

  package My::Serializer::XML;

  @My::Serializer::XML::ISA = 'SOAP::Serializer';

  sub encode_array {
my($self, $array, $name, $type, $attr) = @_;

my $items = join '', 'Array', map("item$_/item", @$array),
'/Array';

return [$name, {'_xml' = 1}, $items];
  }

  package My::Serializer::XMLtag;

  @My::Serializer::XMLtag::ISA = 'SOAP::Serializer';

  sub encode_array {
my($self, $array, $name, $type, $attr) = @_;

my $items = join '', 'Array', map($self-tag('item', {}, $_),
@$array), '/Array';

return [$name, {'_xml' = 1}, $items];
  }
}

# -- -- -- -- -- -- -- -- -- -- --

Hope it gives you some ideas.

Best wishes, Paul.

--- Gunther Birznieks [EMAIL PROTECTED] wrote:
 At 05:14 PM 2/24/2001 -0800, Paul Kulchenko wrote:
 That's right, but first Perl caches calls that involve inheritance
 and second, I use the same scheme, because arrays can have
 everything
 inside and I need to call serialization function for every element
 in
 array. I did profiling for several versions and did some
 improvements, but there is no obvious stopper.
 
 Is there any way to add an interface to basically provide
 serialization and 
 deserialization hints? My experience in the way we use SOAP is that
 there 
 are only a few core objects that really require SOAP and the rest
 can be on 
 the front-end.
 
 Maybe using a CORBA-like IDL config? Thus, I could give a strong
 hint to 

[ANNOUNCE] Apache::SOAP 0.47 (mod_soap)

2001-02-23 Thread Paul Kulchenko

Apache::SOAP provides SOAP server functionality by simply adding 
couple of line in .htaccess or .conf file. Based on SOAP::Lite 
module, hence inherits all functionality, like, for example, 
compression on wire introduced in last version. For now released as
part of SOAP::Lite module. 
Is there any value to ship it separately (probably as a mod_soap)? 

Module is available from www.soaplite.com or CPAN.

Documentation and examples are included. Any comments are very 
welcome.

Best wishes, Paul.

=head1 NAME

Apache::SOAP - Provide SOAP server functionality with simple 
configuration

=head1 SYNOPSIS

=over 4

=item httpd.conf (Location), directory-based access

  Location /mod_soap
SetHandler perl-script
PerlHandler Apache::SOAP
PerlSetVar dispatch_to "/Your/Path/To/Deployed/Modules, 
Module::Name, Module::method"
PerlSetVar options "compress_threshold = 1"
  /Location

=item httpd.conf (Files), file-based access

  FilesMatch "\.soap$"
SetHandler perl-script
PerlHandler Apache::SOAP
PerlSetVar dispatch_to "/Your/Path/To/Deployed/Modules, 
Module::Name, Module::method"
PerlSetVar options "compress_threshold = 1"
  /FilesMatch

=item .htaccess, directory-based access

  SetHandler perl-script
  PerlHandler Apache::SOAP
  PerlSetVar dispatch_to "/Your/Path/To/Deployed/Modules, 
Module::Name, Module::method"
  PerlSetVar options "compress_threshold = 1"

=back

=head1 DESCRIPTION

This Apache Perl module provides the ability to add support for SOAP 
(Simple 
Object Access Protocol) protocol with easy configuration (either 
in .conf or 
in .htaccess file). This functionality should give you lightweight 
option
for hosting SOAP services and greatly simplify configuration aspects.

This
module inherites functionality from SOAP::Transport::HTTP::Apache 
component
of SOAP::Lite module.
 
=head1 CONFIGURATION

The module can be placed in Location, Directory, Files, 
FilesMatch
directives in main server configuration areas or directly 
in .htaccess file.

All parameters should be quoted and can be separated with commas or 
spaces 
for lists ("a, b, c") and with 'wide arrows' and commas for hash 
parameters 
("key1 = value1, key2 = value2").

All options that you can find in SOAP::Transport::HTTP::Apache 
component
are available for configuration. Here is the description of most 
important
ones.

=over 4

=item dispatch_to (LIST)

Specifies path to directory that contains Perl modules you'd like to 
give 
access to, or just list of modules (for preloaded modules).

  PerlSetVar dispatch_to "/Your/Path/To/Deployed/Modules, 
Module::Name, Module::method"

=item options (HASH)

Specifies list of options for your module, for example threshold for 
compression. Future versions will support more options. See 
SOAP::Transport::HTTP documentation for other options.

  PerlSetVar options "compress_threshold = 1"

=back

=head1 DEPENDENCIES

 SOAP::Lite
 mod_perl

=head1 SEE ALSO

 SOAP::Transport::HTTP::Apache for implementation details,
 SOAP::Lite for general information, and
 Fexamples/server/mod_soap.htaccess for .htaccess example

=head1 COPYRIGHT

Copyright (C) 2000-2001 Paul Kulchenko. All rights reserved.

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.

=head1 AUTHOR

Paul Kulchenko ([EMAIL PROTECTED])

=cut


__
Do You Yahoo!?
Yahoo! Auctions - Buy the things you want at great prices! http://auctions.yahoo.com/



Re: [ANNOUNCE] Apache::SOAP 0.47 (mod_soap)

2001-02-23 Thread Gunther Birznieks

Hmmm, I am under the impression that the DevelopMentor stuff has a mod_perl 
SOAP Handler (although I was never able to get it to work) so calling this 
one Apache::SOAP in the official name space seems a difficult sell unless 
you are dedicated to supporting the full SOAP API (not sure what SOAP::Lite 
leaves out).

In that case, maybe you should call it Apache::SOAP::Lite rather than 
Apache::SOAP

The benefit of breaking out Apache::SOAP(::Lite) into its own CPAN module 
is that it will be easier for people to find your module. People who see 
the APache::* module list and are looking for SOAP will say "Ah ha!" and 
find out about your SOAP::Lite module and vice versa. It's like getting two 
directory entries for the price of one. :)

The annoying thing about breaking it out in its own module is that you 
might be tying Apache::SOAP tightly to the version of SOAP::Lite. If you 
consistently release new versions of both at the same time, then it will be 
a pain for people to constantly know they have two packages to download 
instead of one (although I guess it can be bundled).

Another positive thing about keeping the bundle under SOAP::Lite is that 
you might consider releasing SOAP::Lite server code for other persistent 
engines like PerlEx, Velocigen, SpeedyCGI, etc... and you could eventually 
add drivers for these in the one package and presumably add SOAP Server 
code that is shared amongst all the servers instead of breaking them out in 
different packages.

Anyway, all I am saying is that in reply to your question about breaking 
out Apache::SOAP is ...

"It depends".

And hopefully these comments will help you decide for yourself what you'd 
like to do.

Thanks,
 Gunther

At 12:42 PM 2/23/2001 -0800, Paul Kulchenko wrote:
Apache::SOAP provides SOAP server functionality by simply adding
couple of line in .htaccess or .conf file. Based on SOAP::Lite
module, hence inherits all functionality, like, for example,
compression on wire introduced in last version. For now released as
part of SOAP::Lite module.
Is there any value to ship it separately (probably as a mod_soap)?

Module is available from www.soaplite.com or CPAN.

Documentation and examples are included. Any comments are very
welcome.

Best wishes, Paul.

=head1 NAME

Apache::SOAP - Provide SOAP server functionality with simple
configuration

=head1 SYNOPSIS

=over 4

=item httpd.conf (Location), directory-based access

   Location /mod_soap
 SetHandler perl-script
 PerlHandler Apache::SOAP
 PerlSetVar dispatch_to "/Your/Path/To/Deployed/Modules,
Module::Name, Module::method"
 PerlSetVar options "compress_threshold = 1"
   /Location

=item httpd.conf (Files), file-based access

   FilesMatch "\.soap$"
 SetHandler perl-script
 PerlHandler Apache::SOAP
 PerlSetVar dispatch_to "/Your/Path/To/Deployed/Modules,
Module::Name, Module::method"
 PerlSetVar options "compress_threshold = 1"
   /FilesMatch

=item .htaccess, directory-based access

   SetHandler perl-script
   PerlHandler Apache::SOAP
   PerlSetVar dispatch_to "/Your/Path/To/Deployed/Modules,
Module::Name, Module::method"
   PerlSetVar options "compress_threshold = 1"

=back

=head1 DESCRIPTION

This Apache Perl module provides the ability to add support for SOAP
(Simple
Object Access Protocol) protocol with easy configuration (either
in .conf or
in .htaccess file). This functionality should give you lightweight
option
for hosting SOAP services and greatly simplify configuration aspects.

This
module inherites functionality from SOAP::Transport::HTTP::Apache
component
of SOAP::Lite module.

=head1 CONFIGURATION

The module can be placed in Location, Directory, Files,
FilesMatch
directives in main server configuration areas or directly
in .htaccess file.

All parameters should be quoted and can be separated with commas or
spaces
for lists ("a, b, c") and with 'wide arrows' and commas for hash
parameters
("key1 = value1, key2 = value2").

All options that you can find in SOAP::Transport::HTTP::Apache
component
are available for configuration. Here is the description of most
important
ones.

=over 4

=item dispatch_to (LIST)

Specifies path to directory that contains Perl modules you'd like to
give
access to, or just list of modules (for preloaded modules).

   PerlSetVar dispatch_to "/Your/Path/To/Deployed/Modules,
Module::Name, Module::method"

=item options (HASH)

Specifies list of options for your module, for example threshold for
compression. Future versions will support more options. See
SOAP::Transport::HTTP documentation for other options.

   PerlSetVar options "compress_threshold = 1"

=back

=head1 DEPENDENCIES

  SOAP::Lite
  mod_perl

=head1 SEE ALSO

  SOAP::Transport::HTTP::Apache for implementation details,
  SOAP::Lite for general information, and
  Fexamples/server/mod_soap.htaccess for .htaccess example

=head1 COPYRIGHT

Copyright (C) 2000-2001 Paul Kulchenko. All rights reserved.

This library is free software; you 

Re: [ANNOUNCE] Apache::SOAP 0.47 (mod_soap)

2001-02-23 Thread Paul Kulchenko

Hi, Gunther!

--- Gunther Birznieks [EMAIL PROTECTED] wrote:
 Hmmm, I am under the impression that the DevelopMentor stuff has a
 mod_perl 
 SOAP Handler (although I was never able to get it to work) so
 calling this 
 one Apache::SOAP in the official name space seems a difficult sell
 unless 
That's true, DM's SOAP module has mod_perl handler, but it's under 
SOAP::Transport::HTTP::Apache namespace, and SOAP::Lite has also
Apache module under the same namespace, but it's just server
implementation, and Apache::SOAP's goal is to provide easy access to
implementation from configuration files (it is actually subclass of
SOAP::Transport::HTTP::Apache).

 you are dedicated to supporting the full SOAP API (not sure what
 SOAP::Lite leaves out).
First thing I did seven months ago was my email to Keith Brown
(author of DM's SOAP/Perl module) about possible ways for cooperation
and I'v been told that he's willing to, but design of his module
should be consistent with other DM's implementations and he has no
plans to change it. There was no easy way to combine our efforts and
I came up with another implementation. Don't want to praise myself,
but feature set seems to be pretty comparable with other toolkits. I
took ::Lite, just because SOAP namespace was already taken. It does
much more than you can expect from something with suffix Lite. "Lite
suffix reflects number of calories you should spend using this
module". 

 In that case, maybe you should call it Apache::SOAP::Lite rather
 than Apache::SOAP
I thought about it, and in fact I released UDDI::Lite, but I also
plan to release DBD::SOAP, DBIx::SOAP and couple of other modules and
don't want to put suffix Lite everywhere, it could lead to confusion.
Also I don't think (IMHO) that DevelopMentor will ever support their
module, since they abandon SOAP development in Java, C++ and Perl and
there is no other SOAP modules in Perl and I don't have plans to stop
development any time soon. Moreover, I have a long TODO list :).

 find out about your SOAP::Lite module and vice versa. It's like
 getting two directory entries for the price of one. :)
Cool :)

 The annoying thing about breaking it out in its own module is that
 you 
 might be tying Apache::SOAP tightly to the version of SOAP::Lite.
 If you 
 consistently release new versions of both at the same time, then it
 will be 
 a pain for people to constantly know they have two packages to
 download instead of one (although I guess it can be bundled).
Right, but there is no module specific code (it basically parameters
parsing), so I think I'll keep it inside SOAP::Lite for one more
version and then release as mod_soap.

 Another positive thing about keeping the bundle under SOAP::Lite is
 that 
 you might consider releasing SOAP::Lite server code for other
 persistent 
 engines like PerlEx, Velocigen, SpeedyCGI, etc... and you could
It works actually with Velocigen and as far as I understand with
PerlEx also, but I don't have any information about SpeedyCGI. It
also provides Daemon, TCP, CGI, IO, POP3 interfaces on server side
(in addition to mod_perl and Apache::Registry) as well as COM
interface and  (hm, did I say already that I don't want to praise
myself?)

 And hopefully these comments will help you decide for yourself what
 you'd like to do.
Definitely, thanks a lot.

Best wishes, Paul.


__
Do You Yahoo!?
Get email at your own domain with Yahoo! Mail. 
http://personal.mail.yahoo.com/