SlideShare una empresa de Scribd logo
1 de 230
Descargar para leer sin conexión
RubyConf 07 ( 2 Nov. 2007 )




AP4R
Kiwamu Kato & Shun’ichi Shinohara
      Future Architect, Inc.



                    1
Introduction


     2
kiwamu
• Majored in Civil Engineering
• Have enhanced and maintained
 messaging middle-ware
 in our company


              3
kiwamu
• Started Ruby last year
• Leader of the AP4R team
• http://d.hatena.ne.jp/kiwamu/
• The first month of marriage
                 4
shino
• Programmer, I love coding !
• The language of the year is C   or Haskell




                  5
shino
• Made a debut to the OSS world
 last year
• http://d.hatena.ne.jp/ita-wasa
• Sunday physicist,
 interested in the string theory
                 6
Corporate profile
• Future Architect, Inc.
• http://www.future.co.jp/en/index.html
• Aiming for optimization and synergy of
    business and IT

•   Headquarters: Tokyo, Japan

•   Foundation: November 28, 1989

•   Number of employees: 594 (as of June 2007)

•   Revenue: ¥14,831M (2006)
                                 7
Agenda
1. Overview ( the most important part. )
2. Lightweight
3. Demo
4. Robust
5. Other features
6. Conclusion


                    8
1. Overview

     9
1-1. What is AP4R ?
1-2. Typical use cases
1-3. What are advantages of AP4R ?
1-4. Case examples


                  10
What is AP4R ?

      11
What is AP4R ?
• A messaging library by Ruby
• Asynchronous Processing for Ruby
• Loose coupling by messaging

                12
Why did we start AP4R ?

• Developed a messaging middle-ware
 in house
• Named “RtFA”

                 13
RtFA

• Pure Java
• Proprietary protocol and API
                            (≠ JMS)

• Time-proven on various systems
                14
One of illustrative cases of “RtFA”
  Mission critical system
in transportation business




        http://japan.internet.com/linuxtoday/20061228/5.html
                      15
Project summary

• Over 100 million package data per day
• Parallel processing
• Load distribution


                  16
Project summary

• Approx. 100 servers
• Used “RtFA”

               17
http://www.pragmaticprogrammer.com/titles/fr_j2r/        http://www.oreilly.co.jp/books/9784873113203/

                                                    18
From RtFA to AP4R

• Based on experiences of Java,
  carefully designed to keep good concepts and
  added “agility”
• Focused on ease of use    API, configuration




                       19
Open source

• Released as OSS last year
• Take advantages of the community
• For “Enterprise”

                20
Typical use cases of AP4R

 • Quicker response to users
 • Load distribution

              21
Quicker response
    to users


       22
If quick response is not needed,

execute it later

               23
Synchronously
Client           Server




              Sequential tasks
         24
Synchronously
Client            Server


              A   B   C   D   E



              Sequential tasks
         24
Better solution
Client   Server Messaging Server




               25
Better solution
Client   Server Messaging Server



         A   B




                 25
Asynchronously
Client   Server Messaging Server



         A   B




                 26
Asynchronously
Client   Server Messaging Server



         A   B           C   D   E




                 26
Typical cases

• Logging
• Sending mail
• Creating heavy summary data

                27
Advanced case

• Intersystem connection


              28
Moreover,
load distribution


        29
Easy to scale out
Client   Server Messaging Server




                30
Easy to scale out
Client   Server Messaging Servers




                31
There are some solutions
that also use messaging service
     in the ( Ruby ) world.



               32
What are AP4R’s
 advantages?


       33
Lightweight
    and

  Robust
     34
Lightweight ?

      35
36
Ruby’s advantages
• Dynamic
• Succinct
• Open class
• Meta programming
• etc..
              37
AP4R realized
• Ease of use
 • Simple API / configuration
 • Seamless collaboration with Rails
• All-in-one support
 • Not only development
 • But also test and operation support
                  38
One of the advantages is



Lightweight
                39
Robust ?

   40
AP4R guarantees
a message delivery


        41
If a message delivery
is NOT guaranteed,...


          42
it may cause

  message lost or
message duplication

           43
In other words...


        44
•No items despite payment !
•Double withdrawals !

             45
Messages should be
delivered in a reliable way,



             46
No matter what happens
    • Database trouble
    • Network trouble
    • Server down
    • Busy and timeout
    • ... etc
              47
The other advantage is



      Robust
                48
AP4R is ..

    49
Lightweight
    and

  Robust
     50
Lightweight          Robust

 Simple API
                      Recovery

          Test support

   Flexible
                         SAF
system design
                51
Case examples

      52
•Online game
      (not opened yet to the public)


•   Interactivemediums.com

                     53
Online game


     54
What is it ?

• From England
• Massively multiplayer web-based
  strategy game
• Late alpha now;
  private beta testing in January 2008



                    55
They use AP4R for
• Mail sending
• Report generation
• Data analysis routines
• A variety of processor-intensive
  processes including database access


                    56
Scale

• Two dedicated AP4R servers
• Four Rails processes per AP4R
• A few hundred messages an hour
• MySQL to store messages

               57
Interactivemediums.com



          58
http://interactivemediums.com/




              59
What is it ?
• From the U.S.
• Provide mobile messaging solutions for clients, as
  well as internal products like TextMe for Business
  ( http://textmeforbusiness.com )
• In production since July 2007

                        60
http://textmeforbusiness.com/




              61
They use AP4R for
• Intersystem connection
 • Inbound queue
 • Outbound queue
 • Routing queue
• Text processing
              62
Alert service on SMS
             AP4R queues
acceptance


             inbound           Text
                            processing


 delivery                                delivery
             outbound
                             delivery
                            processing

                                                Third Party
             routing                            application


                       63
Scale
• Three AP4R processes
• Four mongrel clusters and so forth
• Now at least a thousand messages a day
  ( Several thousand messages a day soon )
• MySQL to store messages

                   64
What did they choose
      AP4R ?


         65
Questionnaire results
• “Easy to distribute a kind of load across
   a number of servers”
• “Easy to scale”
• “Development is active”
• “Development team had real-world experience
   with the technology”

                       66
Coffee break

     67
:Firefox =>




              (c) 2007 Mozilla Japan
         68
Only in Japan ?
                       Foxkeh




      :Firefox =>




                          (c) 2007 Mozilla Japan
                  69
Duke




:Java =>




                   https://duke.dev.java.net/
       70
cute ! / cute ?

       71
Mascot matters

      72
:AP4R => ...


     73
Copyright © 2007 by Kanican




                 Licensed under Creative Commons License.

                              74
What / Why is that ?
> “AP4R”.sub(/4/,             ”A”)

> “APAR”.downcase
> “apar”
• Three-banded armadillo

            Dictionary    http://www.alc.co.jp/
            Photo   http://www.flickr.com/photos/jeffclow/29738818/
                         75
Copyright © 2007 by Kanican




                 Licensed under Creative Commons License.
                            76
Copyright © 2007 by Kanican




                              77
His name is




Maro 78
Coffee break is done :-)



           79
2. Lightweight

      80
Lightweight          Robust

 Simple API
                      Recovery

          Test support

   Flexible
                         SAF
system design
                81
2-1. Simple API

2-2. Flexible system design

             82
Simple API

    83
API to put messages



         84
ap4r.async_to({destination},
              {data}
              [,{options}])


   There’s also a block style
   c.f. RDoc: http://ap4r.rubyforge.org/doc/


                  85
Class AsyncShopController < ApplicationController

 def order           # synchronous part
   o = Order.new(:name => params[:name])
   o.save!
   ap4r.async_to({:action => ‘payment’},
                 {:order_id => o.id})

   redirect_to ...
 end

 def payment         # asynchronous part
   Payment.new(:order_id => params[:order_id]).save!
   ...
   render :text => ‘true’
 end

end
                         86
Process flow


     87
User   Apache   Rails   AP4R




                88
User   Apache       Rails   AP4R

            order
                            message put




                    89
User   Apache   Rails              AP4R




                        dispatch
                90
User   Apache    Rails   AP4R




           payment

                 91
Flexible
system design

      92
Typical design


      93
User   Apache   Rails   AP4R




                94
Load distribution
for AP4R servers



        95
User   Apache   Rails   AP4R




                96
Separate servers
 for sync/async



       97
User   Apache      Rails   AP4R

           sync




           async


                   98
Separate servers
including reverse proxy



           99
User   Apache   Rails      AP4R




                        URL rewrite




                100
User   Apache      Rails      AP4R




                           URL rewrite
                HTTP




                   100
User   Apache      Rails      AP4R




                           URL rewrite
                HTTP




                   101
Dispatcher
            Producer          Messaging        Consumer

 AP4R

                       put                dispatch


Generally
                       put                    get

                             102
Protocols

• Default is HTTP POST
• Now supported
  • SOAP
  • XML-RPC
  • dRuby
              103
Flow management



       104
Two kinds of tasks
                        processing
               number
                           time

Task “busy”    many       short

Task “heavy”    few     very long
                 105
Configuration
dispatchers:
  -
    targets: queue.very_busy.*
    threads: 10
    modify_rules:
      url: proc {|url| url.host = quot;busy.async.hostquot;}
  -
    targets: queue.very_heavy.*
    threads: 1
    modify_rules:
      url: proc {|url| url.host = quot;heavy.async.hostquot;}


                         106
busy


URL rewrite


               heavy




         107
Lightweight           Robust

 Simple API
                       Recovery

          Test support

   Flexible
                          SAF
system design
                108
3. Demo

   109
Outline
• Shopping store application
• Order and payment


               110
Shopping store app.
 Client           Server


                 A       B


                order payment

          111
Better solution
                          AP4R
Client      Rails                Rails × 3




                    112
Synch’ly order
                         AP4R
Client     Rails                Rails × 3




             A


           order

                   113
Async’ly payment
                       AP4R
Client   Rails                Rails × 3




           A                      B


         order                payment

                 114
Monitor message status
                       AP4R
Client   Rails                Rails × 3




                        100
                         75
                         50
                         25
                          0


                 115
Outline
• Use mongrel cluster
• Stress by ab
• Monitor queue retaining status

               116
117
118
Agenda
1. Overview ( the most important part. )
2. Lightweight
3. Demo
4. Robust
5. Other features
6. Conclusion


                    119
4. Robust

    120
Lightweight           Robust

 Simple API
                       Recovery

          Test support

   Flexible
                          SAF
system design
                121
Stored And Forward



        122
Ensure
     Atomicity
of application transaction
  and putting messages

            123
Rails             app-DB         AP4R      msg-DB


         CRUD          Store
        SAF create
         commit
                           Forward
                     message put
                                  insert /commit

        SAF delete
                      ✓
                           124
Enterprise Integration Patterns:
      Designing, Building, and
      Deploying Messaging Solutions
       by Gregor Hohpe,Bobby Woolf


  Guaranteed Delivery [122]




125
Details



   126
Typical flow
to create async. messages



            127
start




end


        128
start
        CRUD




end


               128
start
        CRUD

        commit




end


                 128
start
        CRUD

        commit

        message put / commit


end


                 128
start
        CRUD

        commit

        message put / commit


end
                 data
                 128
start
        CRUD

        commit

        message put / commit


end
                 data      messages
                 128
Ensure
     Atomicity
of application transaction
  and putting messages

            129
On updating database

• If error occurs,
• Any following messages
   must NOT be queued


              130
On updating database

• If everything succeeded,
• All following messages
       must be queued


                131
☺
Relief

  132
Lightweight
    and

  Robust
     133
Ap4r::Client#transaction
Class ShopController < ApplicationController
  def order             # synchronous side
    ap4r.transaction do
      o = Order.new(:name => params[:order_id])
      o.save!

     ap4r.async_to({:action => ‘payment’},
                   {:order_id => o.id})

    end

    redirect_to ...
  end
end
                       134
Process flow changes
in queueing sequence


         135
Behind ap4r.transaction

ap4r.transaction do
  ...               # CRUD on database

 ap4r.async_to(...)




end
                        136
Behind ap4r.transaction

ap4r.transaction do
  ...               # CRUD on database


                      Insert into SAF table
 ap4r.async_to(...)




end
                        136
Behind ap4r.transaction

ap4r.transaction do
  ...               # CRUD on database


                      Insert into SAF table
 ap4r.async_to(...)




end                     Commit database



                        136
Behind ap4r.transaction

ap4r.transaction do
  ...               # CRUD on database


                      Insert into SAF table
 ap4r.async_to(...)




end                     Commit database
                        Queue messages


                        136
Behind ap4r.transaction

ap4r.transaction do
  ...               # CRUD on database


                      Insert into SAF table
 ap4r.async_to(...)

                                      Store


end                     Commit database
                        Queue messages


                        136
Behind ap4r.transaction

ap4r.transaction do
  ...               # CRUD on database


                      Insert into SAF table
 ap4r.async_to(...)

                                      Store


end                     Commit database
                        Queue messages
                                   Forward
                        136
Sequence in detail
  Without SAF



        137
start
        CRUD

        commit

        message put / commit


end
                 data          messages

                   138
start
        CRUD

        commit

        message put / commit


end
                 data          messages

                   138
start
        CRUD

        commit

        message put / commit


end
                 data          messages

                   139
start
        CRUD

        commit

        message put / commit


end
                 data          messages

                   139
start
        CRUD

        commit

        message put / commit



                         ☠
end
                 data          messages

                   139
start
        CRUD

        commit

        message put / commit



                         ☠
end
                 data          messages

                   139
start
        CRUD

        commit

        message put / commit



                         ☠
end
                 data          messages

                   139
start
        CRUD

        commit
                                counterchange
        message put / commit


end
                 data          messages

                   140
start
        CRUD

         message put / commit
                                counterchange
        commit


end
                 data       messages

                   141
start
        CRUD

         message put / commit

        commit


end
                 data       messages

                   142
start
        CRUD

         message put / commit

        commit


end
                 data       messages

                   142
start
        CRUD

         message put / commit

        commit


end
                 data       messages

                   143
start
        CRUD

         message put / commit

        commit


end
                 data       messages

                   143
start
        CRUD

         message put / commit

        commit



                         ☠
end
                 data        messages

                   143
start
        CRUD

         message put / commit

        commit



                         ☠
end
                 data        messages

                   143
start
        CRUD

         message put / commit

        commit



                         ☠
end
                 data        messages

                   143
Better Safe than Sorry
   • Database trouble
   • Network trouble
   • Server down
   • busy and timeout
   • ... etc
           144
☺
Embrace every exceptions
          ☠
           145
Sequence in detail
   With SAF



        146
CRUD
start
        SAF create

         commit
          message put / commit

        SAF update
end
                data             messages

                     147
CRUD
start
        SAF create

         commit
          message put / commit

        SAF update
end
                data             messages

                     148
CRUD
start
        SAF create

         commit
          message put / commit

        SAF update
end
                data             messages

                     148
CRUD
start
        SAF create

         commit
          message put / commit

        SAF update
end
                data             messages

                     149
CRUD
start
        SAF create

         commit
          message put / commit

        SAF update
end
                data             messages

                     149
CRUD
start
        SAF create

         commit
          message put / commit

        SAF update
end
                data             messages

                     149
CRUD
start
        SAF create

         commit
          message put / commit

        SAF update

                           ☺
end
                data             messages

                     149
CRUD
start
        SAF create

         commit
          message put / commit

        SAF update

                           ☺
end
                data             messages

                     149
CRUD
start
        SAF create

         commit
          message put / commit

        SAF update

                           ☺
end
                data             messages

                     149
CRUD
start
        SAF create

         commit
          message put / commit

        SAF update
end
                data             messages

                     150
CRUD
start
        SAF create

         commit
          message put / commit

        SAF update
end
                data             messages

                     150
CRUD
start
        SAF create

         commit
          message put / commit

        SAF update
end
                data             messages

                     151
CRUD
start
        SAF create

         commit
          message put / commit

        SAF update
end
                data             messages

                     151
CRUD
start
        SAF create

         commit
          message put / commit

        SAF update
end
               data              messages
             messages
                     151
CRUD
start
        SAF create

         commit
          message put / commit

        SAF update

                           ☺
end
               data              messages
             messages
                     151
CRUD
start
        SAF create

         commit
          message put / commit
                           Recoverable
        SAF update

                           ☺
end
               data               messages
             messages
                     151
CRUD
start
        SAF create

         commit
          message put / commit

        SAF update

                           ☺
end
               data              messages
             messages
                     151
CRUD
start
        SAF create

         commit
          message put / commit

        SAF update

                           ☺
end
               data              messages
             messages
                     151
CRUD
start
        SAF create

         commit
          message put / commit

        SAF update
end
                data             messages

                     152
CRUD
start
        SAF create

         commit
          message put / commit

        SAF update
end
                data             messages

                     152
CRUD
start
        SAF create

         commit
          message put / commit

        SAF update
end
                data             messages

                     153
CRUD
start
        SAF create

         commit
          message put / commit

        SAF update
end
               data              messages
             messages
                     153
CRUD
start
        SAF create

         commit
          message put / commit

        SAF update

                           ☺
end
               data              messages
             messages
                     153
CRUD
start
        SAF create

         commit
          message put / commit

                           Duplicated
        SAF update

                           ☺
end
               data               messages
             messages
                     153
CRUD
start
        SAF create

         commit
          message put / commit

        SAF update

                           ☺
end
               data              messages
             messages
                     153
CRUD
start
        SAF create

         commit
          message put / commit

        SAF update

                           ☺
end
               data              messages
             messages
                     153
Ensure
     Atomicity
of application transaction
   and putting message

            154
at-least-once
between Producer and Channel



             155
Lightweight           Robust

 Simple API
                       Recovery

          Test support

   Flexible
                          SAF
system design
                156
5. Other features

        157
• Messages recovery
 when some troubles happen
• Collaboration with Capistrano (2.x)
• Test support

                 158
Test support

     159
TDD / BDD

    160
☺
It makes us feel relieved in
 developing an application



             161
On async app.
• Test matters also, but ..
• Multiple processes
 communicating via N/W
 • take time
 • annoying to setup
               162
Two ways of testing
 • Functional test
  • no N/W communication
  • fast but restricted
 • Async test
  • using N/W communication
  • slow but close to actual
             163
Functional test


• Provided a queue stub
• Executed in memory, quickly

              164
code sample
test code here is against a ‘fictional’ on-line shop
  application, which has an order action (sync)
           and payment action (async).


                       165
def test_order
  post :order, :order => {:item => quot;introduction to AP4Rquot;}
  assert_response :redirect
  assert_redirected_to :action => 'index'

  messages = @controller.ap4r.queued_messages                           # ... (1)
  assert_equal 1, messages.keys.size, quot;should have messages in just ONE queuequot;
  assert messages.key?(quot;queue.async_shop.paymentquot;), quot;queue name is INCORRECTquot;
                                                                        # ... (2)
  assert_equal 1, messages[quot;queue.async_shop.paymentquot;].size,
    quot;should have just ONE message for paymentquot;
  assert_match /order_id=d+/, messages[quot;queue.async_shop.paymentquot;].first[:body],
    quot;parameter order_id should be included with a numeric valuequot;        # ... (3)
end




           1. get (stubbed)queued messages
           2. assert the queue name
           3. assert the message content

                                         166
functional test


rake ..         CRUD


            message put
                        Stub
            assert

            assert


                  167
Async test
• Get on reality
• Test everything, e.g
 serialization, cooperation.



               168
code sample
test code here is against a ‘fictional’ application.



                        169
[RAILS_ROOT]/test/async/ap4r_test_helper.rb
 ENV[quot;RAILS_ENVquot;] = quot;testquot;
 require File.expand_path(File.dirname(__FILE__) + quot;/../../config/environmentquot;)
 require quot;ap4r/service_handlerquot;

 ap4r_test_helper = Ap4r::ServiceHandler.new

 require 'test_help'

 class Test::Unit::TestCase
   self.use_transactional_fixtures = false
   self.use_instantiated_fixtures = false

   # Add more helper methods to be used by all tests here...
   cattr_accessor :ap4r_helper

   def ap4r_helper
     @@ap4r_helper
   end

   def with_services(&block)
     ap4r_helper.with_services(&block)
   end
 end

Test::Unit::TestCase.ap4r_helper = ap4r_test_helper

                                             170
[RAILS_ROOT]/test/async/async_shop_test.rb
require quot;#{File.dirname(__FILE__)}/ap4r_test_helperquot;
require 'net/http'

class AsyncShopTest < Test::Unit::TestCase

  def test_http_dispatch
    ap4r_helper.stop_dispatchers      # ... (1)

    assert_rows_added(Order, 1) {     # ... (3)
      do_order                        # ... (2)
    }
    assert_rows_added(Payment, 1) {   # ... (6)
      ap4r_helper.start_dispatchers   # ... (4)
      ap4r_helper.wait_all_done       # ... (5)
    }
  end

  private
  # Requests to <tt>async_shop/order</tt>.
  def do_order(item_name = quot;test itemquot;)
    Net::HTTP.start(quot;localhostquot;, 3000, nil, nil) do |http|
      http.request_post(quot;/async_shop/orderquot;,
                        quot;order[item]=#{item_name}quot;) do |res|
        #nop
      end
    end
  end

  def assert_rows_added(model, rows)
    rows_before = model.count
    yield
    rows_after = model.count
    assert_equal rows, rows_after - rows_before, quot;table '#{model.table_name}' should count up by #{rows}quot;
  end
end



                                                               171
stop dispatcher threads
1.
     request to Rails with HTTP POST
2.
     assert one row added to orders table
3.
     start dispatcher threads
4.
     wait for async action is completed
5.
     assert one row added to payments table
6.




                      172
async test


rake ..
                 service control
            HTTP
                            CRUD

                            message put
             assert
                                          HTTP
                            CRUD
             assert

                      173
Summary
• Two test methods.
 • Functional test
 • Async test
• It makes us feel relieved to
 develop an application

               174
6. Conclusion

      175
AP4R is ..

    176
Lightweight
    and

  Robust
     177
Lightweight           Robust

 Simple API
                       Recovery

          Test support

   Flexible
                          SAF
system design
                178
• Messaging with simple API,
 simple configuration

• Seamless collaboration with Rails
• Flexible system design
                179
• Automatically invocation of
 async. processing by dispatcher

• Guaranteed delivery by SAF
• Test support
• Recovery and deployment
              180
Future Plans


     181
Smooth operation ver.0.3.x

☑ Daemonize
☑ URL-rewrite filter
☑ DLQ / SAF recovery
□ Protocols: Stomp, HTTP
             182
Monitoring ver.0.4.x

□ Coordinate with Cacti,
  ZABBIX, etc.
□ Many AP4R processes
□ Interactive management tool
             183
Step to large scale   ver.0.5.x




□ Dynamic configuration
□ Automatic recovery
□ Long run 24/7
            184
Others
□ Security
☑ Application testing support
□ Blocking queues
□ Ruby off Rails
              185
AP4R@RubyForge
• wiki: http://ap4r.rubyforge.org/wiki/wiki.pl?HomePage

• source:    svn co http://ap4r.rubyforge.org/svn/trunk/ap4r


• ML: http://rubyforge.org/mailman/listinfo/ap4r-user


Your patches are welcome!
Thank you.


                                                               by Kanican
                              186
•   Future Architect logo belongs to Future Architect, Inc.
    Japan. All rights reserved.

•   Rails logo is trademarks of David Heinemeier
    Hansson. All rights reserved.

•   The Ruby logo is copyrighted (c) 2006, Yukihiro
    Matsumoto. It is released under the terms of the
    Creative Commons Attribution-ShareAlike 2.5 License.




                            187

Más contenido relacionado

La actualidad más candente

Windows Server 2012 Seminar 4 - De mogelijkheden van Direct Access
Windows Server 2012 Seminar 4 - De mogelijkheden van Direct AccessWindows Server 2012 Seminar 4 - De mogelijkheden van Direct Access
Windows Server 2012 Seminar 4 - De mogelijkheden van Direct AccessCompuTrain. De IT opleider.
 
Webinar slides: Managing MySQL Replication for High Availability
Webinar slides: Managing MySQL Replication for High AvailabilityWebinar slides: Managing MySQL Replication for High Availability
Webinar slides: Managing MySQL Replication for High AvailabilitySeveralnines
 
HBase replication
HBase replicationHBase replication
HBase replicationwchevreuil
 
Software And The Taste Of Mayo - Marco Tabini
Software And The Taste Of Mayo - Marco TabiniSoftware And The Taste Of Mayo - Marco Tabini
Software And The Taste Of Mayo - Marco Tabinidpc
 
Deployment With Subversion - Lorna Mitchell
Deployment With Subversion - Lorna MitchellDeployment With Subversion - Lorna Mitchell
Deployment With Subversion - Lorna Mitchelldpc
 
HBase Replication for Bulk Loaded Data
HBase Replication for Bulk Loaded DataHBase Replication for Bulk Loaded Data
HBase Replication for Bulk Loaded DataAshish Singhi
 
Sharing experience implementing Direct NFS
Sharing experience implementing Direct NFSSharing experience implementing Direct NFS
Sharing experience implementing Direct NFSYury Velikanov
 
VMworld 2013: VMware Virtual SAN Technical Best Practices
VMworld 2013: VMware Virtual SAN Technical Best Practices VMworld 2013: VMware Virtual SAN Technical Best Practices
VMworld 2013: VMware Virtual SAN Technical Best Practices VMworld
 
Measuring IPv6 using ad-based measurement
Measuring IPv6 using ad-based measurementMeasuring IPv6 using ad-based measurement
Measuring IPv6 using ad-based measurementAPNIC
 
[Hic2011] using hadoop lucene-solr-for-large-scale-search by systex
[Hic2011] using hadoop lucene-solr-for-large-scale-search by systex[Hic2011] using hadoop lucene-solr-for-large-scale-search by systex
[Hic2011] using hadoop lucene-solr-for-large-scale-search by systexJames Chen
 
Riding the Stream Processing Wave (Strange loop 2019)
Riding the Stream Processing Wave (Strange loop 2019)Riding the Stream Processing Wave (Strange loop 2019)
Riding the Stream Processing Wave (Strange loop 2019)Samarth Shetty
 
Building Linux IPv6 DNS Server (Draft Copy)
Building Linux IPv6 DNS Server (Draft Copy)Building Linux IPv6 DNS Server (Draft Copy)
Building Linux IPv6 DNS Server (Draft Copy)Hari
 
Become a MySQL DBA: performing live database upgrades - webinar slides
Become a MySQL DBA: performing live database upgrades - webinar slidesBecome a MySQL DBA: performing live database upgrades - webinar slides
Become a MySQL DBA: performing live database upgrades - webinar slidesSeveralnines
 
Ren cao kafka connect
Ren cao   kafka connectRen cao   kafka connect
Ren cao kafka connectNitin Kumar
 
L3DSR - Overcoming Layer 2 Limitations of Direct Server Return Load Balancing
L3DSR - Overcoming Layer 2 Limitations of Direct Server Return Load BalancingL3DSR - Overcoming Layer 2 Limitations of Direct Server Return Load Balancing
L3DSR - Overcoming Layer 2 Limitations of Direct Server Return Load BalancingJan Schaumann
 
HTTP/2 Comes to Java: Servlet 4.0 and what it means for the Java/Jakarta EE e...
HTTP/2 Comes to Java: Servlet 4.0 and what it means for the Java/Jakarta EE e...HTTP/2 Comes to Java: Servlet 4.0 and what it means for the Java/Jakarta EE e...
HTTP/2 Comes to Java: Servlet 4.0 and what it means for the Java/Jakarta EE e...Edward Burns
 
GraphConnect Europe 2016 - Moving Graphs to Production at Scale - Ian Robinson
GraphConnect Europe 2016 - Moving Graphs to Production at Scale - Ian RobinsonGraphConnect Europe 2016 - Moving Graphs to Production at Scale - Ian Robinson
GraphConnect Europe 2016 - Moving Graphs to Production at Scale - Ian RobinsonNeo4j
 
Are we really ready to turn off IPv4?
Are we really ready to turn off IPv4?Are we really ready to turn off IPv4?
Are we really ready to turn off IPv4?APNIC
 
High Availability in OpenStack Cloud
High Availability in OpenStack CloudHigh Availability in OpenStack Cloud
High Availability in OpenStack CloudQiming Teng
 
Open Connect Firmware Delivery With Spinnaker (Spinnaker Summit 2018)
Open Connect Firmware Delivery With Spinnaker (Spinnaker Summit 2018)Open Connect Firmware Delivery With Spinnaker (Spinnaker Summit 2018)
Open Connect Firmware Delivery With Spinnaker (Spinnaker Summit 2018)Asher Feldman
 

La actualidad más candente (20)

Windows Server 2012 Seminar 4 - De mogelijkheden van Direct Access
Windows Server 2012 Seminar 4 - De mogelijkheden van Direct AccessWindows Server 2012 Seminar 4 - De mogelijkheden van Direct Access
Windows Server 2012 Seminar 4 - De mogelijkheden van Direct Access
 
Webinar slides: Managing MySQL Replication for High Availability
Webinar slides: Managing MySQL Replication for High AvailabilityWebinar slides: Managing MySQL Replication for High Availability
Webinar slides: Managing MySQL Replication for High Availability
 
HBase replication
HBase replicationHBase replication
HBase replication
 
Software And The Taste Of Mayo - Marco Tabini
Software And The Taste Of Mayo - Marco TabiniSoftware And The Taste Of Mayo - Marco Tabini
Software And The Taste Of Mayo - Marco Tabini
 
Deployment With Subversion - Lorna Mitchell
Deployment With Subversion - Lorna MitchellDeployment With Subversion - Lorna Mitchell
Deployment With Subversion - Lorna Mitchell
 
HBase Replication for Bulk Loaded Data
HBase Replication for Bulk Loaded DataHBase Replication for Bulk Loaded Data
HBase Replication for Bulk Loaded Data
 
Sharing experience implementing Direct NFS
Sharing experience implementing Direct NFSSharing experience implementing Direct NFS
Sharing experience implementing Direct NFS
 
VMworld 2013: VMware Virtual SAN Technical Best Practices
VMworld 2013: VMware Virtual SAN Technical Best Practices VMworld 2013: VMware Virtual SAN Technical Best Practices
VMworld 2013: VMware Virtual SAN Technical Best Practices
 
Measuring IPv6 using ad-based measurement
Measuring IPv6 using ad-based measurementMeasuring IPv6 using ad-based measurement
Measuring IPv6 using ad-based measurement
 
[Hic2011] using hadoop lucene-solr-for-large-scale-search by systex
[Hic2011] using hadoop lucene-solr-for-large-scale-search by systex[Hic2011] using hadoop lucene-solr-for-large-scale-search by systex
[Hic2011] using hadoop lucene-solr-for-large-scale-search by systex
 
Riding the Stream Processing Wave (Strange loop 2019)
Riding the Stream Processing Wave (Strange loop 2019)Riding the Stream Processing Wave (Strange loop 2019)
Riding the Stream Processing Wave (Strange loop 2019)
 
Building Linux IPv6 DNS Server (Draft Copy)
Building Linux IPv6 DNS Server (Draft Copy)Building Linux IPv6 DNS Server (Draft Copy)
Building Linux IPv6 DNS Server (Draft Copy)
 
Become a MySQL DBA: performing live database upgrades - webinar slides
Become a MySQL DBA: performing live database upgrades - webinar slidesBecome a MySQL DBA: performing live database upgrades - webinar slides
Become a MySQL DBA: performing live database upgrades - webinar slides
 
Ren cao kafka connect
Ren cao   kafka connectRen cao   kafka connect
Ren cao kafka connect
 
L3DSR - Overcoming Layer 2 Limitations of Direct Server Return Load Balancing
L3DSR - Overcoming Layer 2 Limitations of Direct Server Return Load BalancingL3DSR - Overcoming Layer 2 Limitations of Direct Server Return Load Balancing
L3DSR - Overcoming Layer 2 Limitations of Direct Server Return Load Balancing
 
HTTP/2 Comes to Java: Servlet 4.0 and what it means for the Java/Jakarta EE e...
HTTP/2 Comes to Java: Servlet 4.0 and what it means for the Java/Jakarta EE e...HTTP/2 Comes to Java: Servlet 4.0 and what it means for the Java/Jakarta EE e...
HTTP/2 Comes to Java: Servlet 4.0 and what it means for the Java/Jakarta EE e...
 
GraphConnect Europe 2016 - Moving Graphs to Production at Scale - Ian Robinson
GraphConnect Europe 2016 - Moving Graphs to Production at Scale - Ian RobinsonGraphConnect Europe 2016 - Moving Graphs to Production at Scale - Ian Robinson
GraphConnect Europe 2016 - Moving Graphs to Production at Scale - Ian Robinson
 
Are we really ready to turn off IPv4?
Are we really ready to turn off IPv4?Are we really ready to turn off IPv4?
Are we really ready to turn off IPv4?
 
High Availability in OpenStack Cloud
High Availability in OpenStack CloudHigh Availability in OpenStack Cloud
High Availability in OpenStack Cloud
 
Open Connect Firmware Delivery With Spinnaker (Spinnaker Summit 2018)
Open Connect Firmware Delivery With Spinnaker (Spinnaker Summit 2018)Open Connect Firmware Delivery With Spinnaker (Spinnaker Summit 2018)
Open Connect Firmware Delivery With Spinnaker (Spinnaker Summit 2018)
 

Destacado

Where God Wants Me
Where God Wants MeWhere God Wants Me
Where God Wants MeMei Su
 
Keystone Foundation
Keystone  FoundationKeystone  Foundation
Keystone Foundationkunaltuk
 
C I N Z A S D E M O M E N T O S
C I N Z A S  D E  M O M E N T O SC I N Z A S  D E  M O M E N T O S
C I N Z A S D E M O M E N T O Sguest2c857d
 
Francesca Fanucci, Ppt
Francesca Fanucci, PptFrancesca Fanucci, Ppt
Francesca Fanucci, Pptguestbc7697
 
Be Like the Internet
Be Like the InternetBe Like the Internet
Be Like the InternetScott Hirsch
 
Touchstones v. 3 - DE IA
Touchstones v. 3 - DE IATouchstones v. 3 - DE IA
Touchstones v. 3 - DE IAJess McMullin
 
Facebook @ Bjec 07
Facebook @ Bjec 07Facebook @ Bjec 07
Facebook @ Bjec 07Daniel Held
 
D I F E R E NÇ A S
D I F E R E NÇ A SD I F E R E NÇ A S
D I F E R E NÇ A Sguest2c857d
 
sightseeing Aso
sightseeing Asosightseeing Aso
sightseeing Asoekkabuuu
 

Destacado (20)

Chinami Nishida
Chinami NishidaChinami Nishida
Chinami Nishida
 
Where God Wants Me
Where God Wants MeWhere God Wants Me
Where God Wants Me
 
Keystone Foundation
Keystone  FoundationKeystone  Foundation
Keystone Foundation
 
Politica
PoliticaPolitica
Politica
 
Adminisalud
AdminisaludAdminisalud
Adminisalud
 
C I N Z A S D E M O M E N T O S
C I N Z A S  D E  M O M E N T O SC I N Z A S  D E  M O M E N T O S
C I N Z A S D E M O M E N T O S
 
Luto
LutoLuto
Luto
 
Francesca Fanucci, Ppt
Francesca Fanucci, PptFrancesca Fanucci, Ppt
Francesca Fanucci, Ppt
 
Ima Miss Ya
Ima  Miss  YaIma  Miss  Ya
Ima Miss Ya
 
Be Like the Internet
Be Like the InternetBe Like the Internet
Be Like the Internet
 
progrmamari liure
progrmamari liureprogrmamari liure
progrmamari liure
 
Kevin Cevey
Kevin CeveyKevin Cevey
Kevin Cevey
 
Touchstones v. 3 - DE IA
Touchstones v. 3 - DE IATouchstones v. 3 - DE IA
Touchstones v. 3 - DE IA
 
Commercial
CommercialCommercial
Commercial
 
Glorified
GlorifiedGlorified
Glorified
 
Ausiàs March
Ausiàs MarchAusiàs March
Ausiàs March
 
Facebook @ Bjec 07
Facebook @ Bjec 07Facebook @ Bjec 07
Facebook @ Bjec 07
 
D I F E R E NÇ A S
D I F E R E NÇ A SD I F E R E NÇ A S
D I F E R E NÇ A S
 
resumen tema 1
resumen tema 1resumen tema 1
resumen tema 1
 
sightseeing Aso
sightseeing Asosightseeing Aso
sightseeing Aso
 

Similar a AP4R on RubyConf2007

AP4R on Developers Summit 2008
AP4R on Developers Summit 2008AP4R on Developers Summit 2008
AP4R on Developers Summit 2008Kato Kiwamu
 
Deployment with Ruby on Rails
Deployment with Ruby on RailsDeployment with Ruby on Rails
Deployment with Ruby on RailsJonathan Weiss
 
Enabling Java: Windows on Arm64 - A Success Story!
Enabling Java: Windows on Arm64 - A Success Story!Enabling Java: Windows on Arm64 - A Success Story!
Enabling Java: Windows on Arm64 - A Success Story!Monica Beckwith
 
HyperLoop: Group-Based NIC-Offloading to Accelerate Replicated Transactions i...
HyperLoop: Group-Based NIC-Offloading to Accelerate Replicated Transactions i...HyperLoop: Group-Based NIC-Offloading to Accelerate Replicated Transactions i...
HyperLoop: Group-Based NIC-Offloading to Accelerate Replicated Transactions i...Daehyeok Kim
 
Messaging With ActiveMQ
Messaging With ActiveMQMessaging With ActiveMQ
Messaging With ActiveMQBruce Snyder
 
High Performance Object Pascal Code on Servers (at EKON 22)
High Performance Object Pascal Code on Servers (at EKON 22)High Performance Object Pascal Code on Servers (at EKON 22)
High Performance Object Pascal Code on Servers (at EKON 22)Arnaud Bouchez
 
PHP Performance with APC + Memcached
PHP Performance with APC + MemcachedPHP Performance with APC + Memcached
PHP Performance with APC + MemcachedFord AntiTrust
 
Ruby on Rails 101 - Presentation Slides for a Five Day Introductory Course
Ruby on Rails 101 - Presentation Slides for a Five Day Introductory CourseRuby on Rails 101 - Presentation Slides for a Five Day Introductory Course
Ruby on Rails 101 - Presentation Slides for a Five Day Introductory Coursepeter_marklund
 
Scalable Persistent Storage for Erlang: Theory and Practice
Scalable Persistent Storage for Erlang: Theory and PracticeScalable Persistent Storage for Erlang: Theory and Practice
Scalable Persistent Storage for Erlang: Theory and PracticeAmir Ghaffari
 
Evergreen Sysadmin Survival Skills
Evergreen Sysadmin Survival SkillsEvergreen Sysadmin Survival Skills
Evergreen Sysadmin Survival SkillsEvergreen ILS
 
AWS and GKE Migration and Multicloud
AWS and GKE Migration and MulticloudAWS and GKE Migration and Multicloud
AWS and GKE Migration and MulticloudChris Gaun
 
Ceph on 64-bit ARM with X-Gene
Ceph on 64-bit ARM with X-GeneCeph on 64-bit ARM with X-Gene
Ceph on 64-bit ARM with X-GeneCeph Community
 
Northeast PHP - High Performance PHP
Northeast PHP - High Performance PHPNortheast PHP - High Performance PHP
Northeast PHP - High Performance PHPJonathan Klein
 
Open Source Integration with WSO2 Enterprise Service Bus
Open Source Integration  with  WSO2 Enterprise Service BusOpen Source Integration  with  WSO2 Enterprise Service Bus
Open Source Integration with WSO2 Enterprise Service Bussumedha.r
 
Deploying And Monitoring Rails
Deploying And Monitoring RailsDeploying And Monitoring Rails
Deploying And Monitoring RailsJonathan Weiss
 

Similar a AP4R on RubyConf2007 (20)

AP4R on Developers Summit 2008
AP4R on Developers Summit 2008AP4R on Developers Summit 2008
AP4R on Developers Summit 2008
 
Deployment with Ruby on Rails
Deployment with Ruby on RailsDeployment with Ruby on Rails
Deployment with Ruby on Rails
 
Enabling Java: Windows on Arm64 - A Success Story!
Enabling Java: Windows on Arm64 - A Success Story!Enabling Java: Windows on Arm64 - A Success Story!
Enabling Java: Windows on Arm64 - A Success Story!
 
HyperLoop: Group-Based NIC-Offloading to Accelerate Replicated Transactions i...
HyperLoop: Group-Based NIC-Offloading to Accelerate Replicated Transactions i...HyperLoop: Group-Based NIC-Offloading to Accelerate Replicated Transactions i...
HyperLoop: Group-Based NIC-Offloading to Accelerate Replicated Transactions i...
 
Messaging With ActiveMQ
Messaging With ActiveMQMessaging With ActiveMQ
Messaging With ActiveMQ
 
YARN
YARNYARN
YARN
 
High Performance Object Pascal Code on Servers (at EKON 22)
High Performance Object Pascal Code on Servers (at EKON 22)High Performance Object Pascal Code on Servers (at EKON 22)
High Performance Object Pascal Code on Servers (at EKON 22)
 
PHP Performance with APC + Memcached
PHP Performance with APC + MemcachedPHP Performance with APC + Memcached
PHP Performance with APC + Memcached
 
MySQL Replication
MySQL ReplicationMySQL Replication
MySQL Replication
 
MySQL Aquarium Paris
MySQL Aquarium ParisMySQL Aquarium Paris
MySQL Aquarium Paris
 
Ruby on Rails 101 - Presentation Slides for a Five Day Introductory Course
Ruby on Rails 101 - Presentation Slides for a Five Day Introductory CourseRuby on Rails 101 - Presentation Slides for a Five Day Introductory Course
Ruby on Rails 101 - Presentation Slides for a Five Day Introductory Course
 
MySQL Fabric
MySQL FabricMySQL Fabric
MySQL Fabric
 
Real World Technologies
Real World TechnologiesReal World Technologies
Real World Technologies
 
Scalable Persistent Storage for Erlang: Theory and Practice
Scalable Persistent Storage for Erlang: Theory and PracticeScalable Persistent Storage for Erlang: Theory and Practice
Scalable Persistent Storage for Erlang: Theory and Practice
 
Evergreen Sysadmin Survival Skills
Evergreen Sysadmin Survival SkillsEvergreen Sysadmin Survival Skills
Evergreen Sysadmin Survival Skills
 
AWS and GKE Migration and Multicloud
AWS and GKE Migration and MulticloudAWS and GKE Migration and Multicloud
AWS and GKE Migration and Multicloud
 
Ceph on 64-bit ARM with X-Gene
Ceph on 64-bit ARM with X-GeneCeph on 64-bit ARM with X-Gene
Ceph on 64-bit ARM with X-Gene
 
Northeast PHP - High Performance PHP
Northeast PHP - High Performance PHPNortheast PHP - High Performance PHP
Northeast PHP - High Performance PHP
 
Open Source Integration with WSO2 Enterprise Service Bus
Open Source Integration  with  WSO2 Enterprise Service BusOpen Source Integration  with  WSO2 Enterprise Service Bus
Open Source Integration with WSO2 Enterprise Service Bus
 
Deploying And Monitoring Rails
Deploying And Monitoring RailsDeploying And Monitoring Rails
Deploying And Monitoring Rails
 

Último

2024 Numerator Consumer Study of Cannabis Usage
2024 Numerator Consumer Study of Cannabis Usage2024 Numerator Consumer Study of Cannabis Usage
2024 Numerator Consumer Study of Cannabis UsageNeil Kimberley
 
Contemporary Economic Issues Facing the Filipino Entrepreneur (1).pptx
Contemporary Economic Issues Facing the Filipino Entrepreneur (1).pptxContemporary Economic Issues Facing the Filipino Entrepreneur (1).pptx
Contemporary Economic Issues Facing the Filipino Entrepreneur (1).pptxMarkAnthonyAurellano
 
Organizational Structure Running A Successful Business
Organizational Structure Running A Successful BusinessOrganizational Structure Running A Successful Business
Organizational Structure Running A Successful BusinessSeta Wicaksana
 
Call Girls In Connaught Place Delhi ❤️88604**77959_Russian 100% Genuine Escor...
Call Girls In Connaught Place Delhi ❤️88604**77959_Russian 100% Genuine Escor...Call Girls In Connaught Place Delhi ❤️88604**77959_Russian 100% Genuine Escor...
Call Girls In Connaught Place Delhi ❤️88604**77959_Russian 100% Genuine Escor...lizamodels9
 
Investment in The Coconut Industry by Nancy Cheruiyot
Investment in The Coconut Industry by Nancy CheruiyotInvestment in The Coconut Industry by Nancy Cheruiyot
Investment in The Coconut Industry by Nancy Cheruiyotictsugar
 
Annual General Meeting Presentation Slides
Annual General Meeting Presentation SlidesAnnual General Meeting Presentation Slides
Annual General Meeting Presentation SlidesKeppelCorporation
 
8447779800, Low rate Call girls in Shivaji Enclave Delhi NCR
8447779800, Low rate Call girls in Shivaji Enclave Delhi NCR8447779800, Low rate Call girls in Shivaji Enclave Delhi NCR
8447779800, Low rate Call girls in Shivaji Enclave Delhi NCRashishs7044
 
Kenya’s Coconut Value Chain by Gatsby Africa
Kenya’s Coconut Value Chain by Gatsby AfricaKenya’s Coconut Value Chain by Gatsby Africa
Kenya’s Coconut Value Chain by Gatsby Africaictsugar
 
The CMO Survey - Highlights and Insights Report - Spring 2024
The CMO Survey - Highlights and Insights Report - Spring 2024The CMO Survey - Highlights and Insights Report - Spring 2024
The CMO Survey - Highlights and Insights Report - Spring 2024christinemoorman
 
FULL ENJOY Call girls in Paharganj Delhi | 8377087607
FULL ENJOY Call girls in Paharganj Delhi | 8377087607FULL ENJOY Call girls in Paharganj Delhi | 8377087607
FULL ENJOY Call girls in Paharganj Delhi | 8377087607dollysharma2066
 
Cybersecurity Awareness Training Presentation v2024.03
Cybersecurity Awareness Training Presentation v2024.03Cybersecurity Awareness Training Presentation v2024.03
Cybersecurity Awareness Training Presentation v2024.03DallasHaselhorst
 
Keppel Ltd. 1Q 2024 Business Update Presentation Slides
Keppel Ltd. 1Q 2024 Business Update  Presentation SlidesKeppel Ltd. 1Q 2024 Business Update  Presentation Slides
Keppel Ltd. 1Q 2024 Business Update Presentation SlidesKeppelCorporation
 
Market Sizes Sample Report - 2024 Edition
Market Sizes Sample Report - 2024 EditionMarket Sizes Sample Report - 2024 Edition
Market Sizes Sample Report - 2024 EditionMintel Group
 
Call Girls In Sikandarpur Gurgaon ❤️8860477959_Russian 100% Genuine Escorts I...
Call Girls In Sikandarpur Gurgaon ❤️8860477959_Russian 100% Genuine Escorts I...Call Girls In Sikandarpur Gurgaon ❤️8860477959_Russian 100% Genuine Escorts I...
Call Girls In Sikandarpur Gurgaon ❤️8860477959_Russian 100% Genuine Escorts I...lizamodels9
 
International Business Environments and Operations 16th Global Edition test b...
International Business Environments and Operations 16th Global Edition test b...International Business Environments and Operations 16th Global Edition test b...
International Business Environments and Operations 16th Global Edition test b...ssuserf63bd7
 
8447779800, Low rate Call girls in Uttam Nagar Delhi NCR
8447779800, Low rate Call girls in Uttam Nagar Delhi NCR8447779800, Low rate Call girls in Uttam Nagar Delhi NCR
8447779800, Low rate Call girls in Uttam Nagar Delhi NCRashishs7044
 
Future Of Sample Report 2024 | Redacted Version
Future Of Sample Report 2024 | Redacted VersionFuture Of Sample Report 2024 | Redacted Version
Future Of Sample Report 2024 | Redacted VersionMintel Group
 
8447779800, Low rate Call girls in Kotla Mubarakpur Delhi NCR
8447779800, Low rate Call girls in Kotla Mubarakpur Delhi NCR8447779800, Low rate Call girls in Kotla Mubarakpur Delhi NCR
8447779800, Low rate Call girls in Kotla Mubarakpur Delhi NCRashishs7044
 
Call US-88OO1O2216 Call Girls In Mahipalpur Female Escort Service
Call US-88OO1O2216 Call Girls In Mahipalpur Female Escort ServiceCall US-88OO1O2216 Call Girls In Mahipalpur Female Escort Service
Call US-88OO1O2216 Call Girls In Mahipalpur Female Escort Servicecallgirls2057
 
Marketplace and Quality Assurance Presentation - Vincent Chirchir
Marketplace and Quality Assurance Presentation - Vincent ChirchirMarketplace and Quality Assurance Presentation - Vincent Chirchir
Marketplace and Quality Assurance Presentation - Vincent Chirchirictsugar
 

Último (20)

2024 Numerator Consumer Study of Cannabis Usage
2024 Numerator Consumer Study of Cannabis Usage2024 Numerator Consumer Study of Cannabis Usage
2024 Numerator Consumer Study of Cannabis Usage
 
Contemporary Economic Issues Facing the Filipino Entrepreneur (1).pptx
Contemporary Economic Issues Facing the Filipino Entrepreneur (1).pptxContemporary Economic Issues Facing the Filipino Entrepreneur (1).pptx
Contemporary Economic Issues Facing the Filipino Entrepreneur (1).pptx
 
Organizational Structure Running A Successful Business
Organizational Structure Running A Successful BusinessOrganizational Structure Running A Successful Business
Organizational Structure Running A Successful Business
 
Call Girls In Connaught Place Delhi ❤️88604**77959_Russian 100% Genuine Escor...
Call Girls In Connaught Place Delhi ❤️88604**77959_Russian 100% Genuine Escor...Call Girls In Connaught Place Delhi ❤️88604**77959_Russian 100% Genuine Escor...
Call Girls In Connaught Place Delhi ❤️88604**77959_Russian 100% Genuine Escor...
 
Investment in The Coconut Industry by Nancy Cheruiyot
Investment in The Coconut Industry by Nancy CheruiyotInvestment in The Coconut Industry by Nancy Cheruiyot
Investment in The Coconut Industry by Nancy Cheruiyot
 
Annual General Meeting Presentation Slides
Annual General Meeting Presentation SlidesAnnual General Meeting Presentation Slides
Annual General Meeting Presentation Slides
 
8447779800, Low rate Call girls in Shivaji Enclave Delhi NCR
8447779800, Low rate Call girls in Shivaji Enclave Delhi NCR8447779800, Low rate Call girls in Shivaji Enclave Delhi NCR
8447779800, Low rate Call girls in Shivaji Enclave Delhi NCR
 
Kenya’s Coconut Value Chain by Gatsby Africa
Kenya’s Coconut Value Chain by Gatsby AfricaKenya’s Coconut Value Chain by Gatsby Africa
Kenya’s Coconut Value Chain by Gatsby Africa
 
The CMO Survey - Highlights and Insights Report - Spring 2024
The CMO Survey - Highlights and Insights Report - Spring 2024The CMO Survey - Highlights and Insights Report - Spring 2024
The CMO Survey - Highlights and Insights Report - Spring 2024
 
FULL ENJOY Call girls in Paharganj Delhi | 8377087607
FULL ENJOY Call girls in Paharganj Delhi | 8377087607FULL ENJOY Call girls in Paharganj Delhi | 8377087607
FULL ENJOY Call girls in Paharganj Delhi | 8377087607
 
Cybersecurity Awareness Training Presentation v2024.03
Cybersecurity Awareness Training Presentation v2024.03Cybersecurity Awareness Training Presentation v2024.03
Cybersecurity Awareness Training Presentation v2024.03
 
Keppel Ltd. 1Q 2024 Business Update Presentation Slides
Keppel Ltd. 1Q 2024 Business Update  Presentation SlidesKeppel Ltd. 1Q 2024 Business Update  Presentation Slides
Keppel Ltd. 1Q 2024 Business Update Presentation Slides
 
Market Sizes Sample Report - 2024 Edition
Market Sizes Sample Report - 2024 EditionMarket Sizes Sample Report - 2024 Edition
Market Sizes Sample Report - 2024 Edition
 
Call Girls In Sikandarpur Gurgaon ❤️8860477959_Russian 100% Genuine Escorts I...
Call Girls In Sikandarpur Gurgaon ❤️8860477959_Russian 100% Genuine Escorts I...Call Girls In Sikandarpur Gurgaon ❤️8860477959_Russian 100% Genuine Escorts I...
Call Girls In Sikandarpur Gurgaon ❤️8860477959_Russian 100% Genuine Escorts I...
 
International Business Environments and Operations 16th Global Edition test b...
International Business Environments and Operations 16th Global Edition test b...International Business Environments and Operations 16th Global Edition test b...
International Business Environments and Operations 16th Global Edition test b...
 
8447779800, Low rate Call girls in Uttam Nagar Delhi NCR
8447779800, Low rate Call girls in Uttam Nagar Delhi NCR8447779800, Low rate Call girls in Uttam Nagar Delhi NCR
8447779800, Low rate Call girls in Uttam Nagar Delhi NCR
 
Future Of Sample Report 2024 | Redacted Version
Future Of Sample Report 2024 | Redacted VersionFuture Of Sample Report 2024 | Redacted Version
Future Of Sample Report 2024 | Redacted Version
 
8447779800, Low rate Call girls in Kotla Mubarakpur Delhi NCR
8447779800, Low rate Call girls in Kotla Mubarakpur Delhi NCR8447779800, Low rate Call girls in Kotla Mubarakpur Delhi NCR
8447779800, Low rate Call girls in Kotla Mubarakpur Delhi NCR
 
Call US-88OO1O2216 Call Girls In Mahipalpur Female Escort Service
Call US-88OO1O2216 Call Girls In Mahipalpur Female Escort ServiceCall US-88OO1O2216 Call Girls In Mahipalpur Female Escort Service
Call US-88OO1O2216 Call Girls In Mahipalpur Female Escort Service
 
Marketplace and Quality Assurance Presentation - Vincent Chirchir
Marketplace and Quality Assurance Presentation - Vincent ChirchirMarketplace and Quality Assurance Presentation - Vincent Chirchir
Marketplace and Quality Assurance Presentation - Vincent Chirchir
 

AP4R on RubyConf2007

  • 1. RubyConf 07 ( 2 Nov. 2007 ) AP4R Kiwamu Kato & Shun’ichi Shinohara Future Architect, Inc. 1
  • 3. kiwamu • Majored in Civil Engineering • Have enhanced and maintained messaging middle-ware in our company 3
  • 4. kiwamu • Started Ruby last year • Leader of the AP4R team • http://d.hatena.ne.jp/kiwamu/ • The first month of marriage 4
  • 5. shino • Programmer, I love coding ! • The language of the year is C or Haskell 5
  • 6. shino • Made a debut to the OSS world last year • http://d.hatena.ne.jp/ita-wasa • Sunday physicist, interested in the string theory 6
  • 7. Corporate profile • Future Architect, Inc. • http://www.future.co.jp/en/index.html • Aiming for optimization and synergy of business and IT • Headquarters: Tokyo, Japan • Foundation: November 28, 1989 • Number of employees: 594 (as of June 2007) • Revenue: ¥14,831M (2006) 7
  • 8. Agenda 1. Overview ( the most important part. ) 2. Lightweight 3. Demo 4. Robust 5. Other features 6. Conclusion 8
  • 10. 1-1. What is AP4R ? 1-2. Typical use cases 1-3. What are advantages of AP4R ? 1-4. Case examples 10
  • 12. What is AP4R ? • A messaging library by Ruby • Asynchronous Processing for Ruby • Loose coupling by messaging 12
  • 13. Why did we start AP4R ? • Developed a messaging middle-ware in house • Named “RtFA” 13
  • 14. RtFA • Pure Java • Proprietary protocol and API (≠ JMS) • Time-proven on various systems 14
  • 15. One of illustrative cases of “RtFA” Mission critical system in transportation business http://japan.internet.com/linuxtoday/20061228/5.html 15
  • 16. Project summary • Over 100 million package data per day • Parallel processing • Load distribution 16
  • 17. Project summary • Approx. 100 servers • Used “RtFA” 17
  • 18. http://www.pragmaticprogrammer.com/titles/fr_j2r/ http://www.oreilly.co.jp/books/9784873113203/ 18
  • 19. From RtFA to AP4R • Based on experiences of Java, carefully designed to keep good concepts and added “agility” • Focused on ease of use API, configuration 19
  • 20. Open source • Released as OSS last year • Take advantages of the community • For “Enterprise” 20
  • 21. Typical use cases of AP4R • Quicker response to users • Load distribution 21
  • 22. Quicker response to users 22
  • 23. If quick response is not needed, execute it later 23
  • 24. Synchronously Client Server Sequential tasks 24
  • 25. Synchronously Client Server A B C D E Sequential tasks 24
  • 26. Better solution Client Server Messaging Server 25
  • 27. Better solution Client Server Messaging Server A B 25
  • 28. Asynchronously Client Server Messaging Server A B 26
  • 29. Asynchronously Client Server Messaging Server A B C D E 26
  • 30. Typical cases • Logging • Sending mail • Creating heavy summary data 27
  • 33. Easy to scale out Client Server Messaging Server 30
  • 34. Easy to scale out Client Server Messaging Servers 31
  • 35. There are some solutions that also use messaging service in the ( Ruby ) world. 32
  • 36. What are AP4R’s advantages? 33
  • 37. Lightweight and Robust 34
  • 39. 36
  • 40. Ruby’s advantages • Dynamic • Succinct • Open class • Meta programming • etc.. 37
  • 41. AP4R realized • Ease of use • Simple API / configuration • Seamless collaboration with Rails • All-in-one support • Not only development • But also test and operation support 38
  • 42. One of the advantages is Lightweight 39
  • 43. Robust ? 40
  • 45. If a message delivery is NOT guaranteed,... 42
  • 46. it may cause message lost or message duplication 43
  • 48. •No items despite payment ! •Double withdrawals ! 45
  • 49. Messages should be delivered in a reliable way, 46
  • 50. No matter what happens • Database trouble • Network trouble • Server down • Busy and timeout • ... etc 47
  • 51. The other advantage is Robust 48
  • 53. Lightweight and Robust 50
  • 54. Lightweight Robust Simple API Recovery Test support Flexible SAF system design 51
  • 56. •Online game (not opened yet to the public) • Interactivemediums.com 53
  • 58. What is it ? • From England • Massively multiplayer web-based strategy game • Late alpha now; private beta testing in January 2008 55
  • 59. They use AP4R for • Mail sending • Report generation • Data analysis routines • A variety of processor-intensive processes including database access 56
  • 60. Scale • Two dedicated AP4R servers • Four Rails processes per AP4R • A few hundred messages an hour • MySQL to store messages 57
  • 63. What is it ? • From the U.S. • Provide mobile messaging solutions for clients, as well as internal products like TextMe for Business ( http://textmeforbusiness.com ) • In production since July 2007 60
  • 65. They use AP4R for • Intersystem connection • Inbound queue • Outbound queue • Routing queue • Text processing 62
  • 66. Alert service on SMS AP4R queues acceptance inbound Text processing delivery delivery outbound delivery processing Third Party routing application 63
  • 67. Scale • Three AP4R processes • Four mongrel clusters and so forth • Now at least a thousand messages a day ( Several thousand messages a day soon ) • MySQL to store messages 64
  • 68. What did they choose AP4R ? 65
  • 69. Questionnaire results • “Easy to distribute a kind of load across a number of servers” • “Easy to scale” • “Development is active” • “Development team had real-world experience with the technology” 66
  • 71. :Firefox => (c) 2007 Mozilla Japan 68
  • 72. Only in Japan ? Foxkeh :Firefox => (c) 2007 Mozilla Japan 69
  • 73. Duke :Java => https://duke.dev.java.net/ 70
  • 74. cute ! / cute ? 71
  • 77. Copyright © 2007 by Kanican Licensed under Creative Commons License. 74
  • 78. What / Why is that ? > “AP4R”.sub(/4/, ”A”) > “APAR”.downcase > “apar” • Three-banded armadillo Dictionary http://www.alc.co.jp/ Photo http://www.flickr.com/photos/jeffclow/29738818/ 75
  • 79. Copyright © 2007 by Kanican Licensed under Creative Commons License. 76
  • 80. Copyright © 2007 by Kanican 77
  • 82. Coffee break is done :-) 79
  • 84. Lightweight Robust Simple API Recovery Test support Flexible SAF system design 81
  • 85. 2-1. Simple API 2-2. Flexible system design 82
  • 87. API to put messages 84
  • 88. ap4r.async_to({destination}, {data} [,{options}]) There’s also a block style c.f. RDoc: http://ap4r.rubyforge.org/doc/ 85
  • 89. Class AsyncShopController < ApplicationController def order # synchronous part o = Order.new(:name => params[:name]) o.save! ap4r.async_to({:action => ‘payment’}, {:order_id => o.id}) redirect_to ... end def payment # asynchronous part Payment.new(:order_id => params[:order_id]).save! ... render :text => ‘true’ end end 86
  • 91. User Apache Rails AP4R 88
  • 92. User Apache Rails AP4R order message put 89
  • 93. User Apache Rails AP4R dispatch 90
  • 94. User Apache Rails AP4R payment 91
  • 97. User Apache Rails AP4R 94
  • 99. User Apache Rails AP4R 96
  • 100. Separate servers for sync/async 97
  • 101. User Apache Rails AP4R sync async 98
  • 103. User Apache Rails AP4R URL rewrite 100
  • 104. User Apache Rails AP4R URL rewrite HTTP 100
  • 105. User Apache Rails AP4R URL rewrite HTTP 101
  • 106. Dispatcher Producer Messaging Consumer AP4R put dispatch Generally put get 102
  • 107. Protocols • Default is HTTP POST • Now supported • SOAP • XML-RPC • dRuby 103
  • 109. Two kinds of tasks processing number time Task “busy” many short Task “heavy” few very long 105
  • 110. Configuration dispatchers: - targets: queue.very_busy.* threads: 10 modify_rules: url: proc {|url| url.host = quot;busy.async.hostquot;} - targets: queue.very_heavy.* threads: 1 modify_rules: url: proc {|url| url.host = quot;heavy.async.hostquot;} 106
  • 111. busy URL rewrite heavy 107
  • 112. Lightweight Robust Simple API Recovery Test support Flexible SAF system design 108
  • 113. 3. Demo 109
  • 114. Outline • Shopping store application • Order and payment 110
  • 115. Shopping store app. Client Server A B order payment 111
  • 116. Better solution AP4R Client Rails Rails × 3 112
  • 117. Synch’ly order AP4R Client Rails Rails × 3 A order 113
  • 118. Async’ly payment AP4R Client Rails Rails × 3 A B order payment 114
  • 119. Monitor message status AP4R Client Rails Rails × 3 100 75 50 25 0 115
  • 120. Outline • Use mongrel cluster • Stress by ab • Monitor queue retaining status 116
  • 121. 117
  • 122. 118
  • 123. Agenda 1. Overview ( the most important part. ) 2. Lightweight 3. Demo 4. Robust 5. Other features 6. Conclusion 119
  • 124. 4. Robust 120
  • 125. Lightweight Robust Simple API Recovery Test support Flexible SAF system design 121
  • 127. Ensure Atomicity of application transaction and putting messages 123
  • 128. Rails app-DB AP4R msg-DB CRUD Store SAF create commit Forward message put insert /commit SAF delete ✓ 124
  • 129. Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions by Gregor Hohpe,Bobby Woolf Guaranteed Delivery [122] 125
  • 130. Details 126
  • 131. Typical flow to create async. messages 127
  • 132. start end 128
  • 133. start CRUD end 128
  • 134. start CRUD commit end 128
  • 135. start CRUD commit message put / commit end 128
  • 136. start CRUD commit message put / commit end data 128
  • 137. start CRUD commit message put / commit end data messages 128
  • 138. Ensure Atomicity of application transaction and putting messages 129
  • 139. On updating database • If error occurs, • Any following messages must NOT be queued 130
  • 140. On updating database • If everything succeeded, • All following messages must be queued 131
  • 142. Lightweight and Robust 133
  • 143. Ap4r::Client#transaction Class ShopController < ApplicationController def order # synchronous side ap4r.transaction do o = Order.new(:name => params[:order_id]) o.save! ap4r.async_to({:action => ‘payment’}, {:order_id => o.id}) end redirect_to ... end end 134
  • 144. Process flow changes in queueing sequence 135
  • 145. Behind ap4r.transaction ap4r.transaction do ... # CRUD on database ap4r.async_to(...) end 136
  • 146. Behind ap4r.transaction ap4r.transaction do ... # CRUD on database Insert into SAF table ap4r.async_to(...) end 136
  • 147. Behind ap4r.transaction ap4r.transaction do ... # CRUD on database Insert into SAF table ap4r.async_to(...) end Commit database 136
  • 148. Behind ap4r.transaction ap4r.transaction do ... # CRUD on database Insert into SAF table ap4r.async_to(...) end Commit database Queue messages 136
  • 149. Behind ap4r.transaction ap4r.transaction do ... # CRUD on database Insert into SAF table ap4r.async_to(...) Store end Commit database Queue messages 136
  • 150. Behind ap4r.transaction ap4r.transaction do ... # CRUD on database Insert into SAF table ap4r.async_to(...) Store end Commit database Queue messages Forward 136
  • 151. Sequence in detail Without SAF 137
  • 152. start CRUD commit message put / commit end data messages 138
  • 153. start CRUD commit message put / commit end data messages 138
  • 154. start CRUD commit message put / commit end data messages 139
  • 155. start CRUD commit message put / commit end data messages 139
  • 156. start CRUD commit message put / commit ☠ end data messages 139
  • 157. start CRUD commit message put / commit ☠ end data messages 139
  • 158. start CRUD commit message put / commit ☠ end data messages 139
  • 159. start CRUD commit counterchange message put / commit end data messages 140
  • 160. start CRUD message put / commit counterchange commit end data messages 141
  • 161. start CRUD message put / commit commit end data messages 142
  • 162. start CRUD message put / commit commit end data messages 142
  • 163. start CRUD message put / commit commit end data messages 143
  • 164. start CRUD message put / commit commit end data messages 143
  • 165. start CRUD message put / commit commit ☠ end data messages 143
  • 166. start CRUD message put / commit commit ☠ end data messages 143
  • 167. start CRUD message put / commit commit ☠ end data messages 143
  • 168. Better Safe than Sorry • Database trouble • Network trouble • Server down • busy and timeout • ... etc 144
  • 170. Sequence in detail With SAF 146
  • 171. CRUD start SAF create commit message put / commit SAF update end data messages 147
  • 172. CRUD start SAF create commit message put / commit SAF update end data messages 148
  • 173. CRUD start SAF create commit message put / commit SAF update end data messages 148
  • 174. CRUD start SAF create commit message put / commit SAF update end data messages 149
  • 175. CRUD start SAF create commit message put / commit SAF update end data messages 149
  • 176. CRUD start SAF create commit message put / commit SAF update end data messages 149
  • 177. CRUD start SAF create commit message put / commit SAF update ☺ end data messages 149
  • 178. CRUD start SAF create commit message put / commit SAF update ☺ end data messages 149
  • 179. CRUD start SAF create commit message put / commit SAF update ☺ end data messages 149
  • 180. CRUD start SAF create commit message put / commit SAF update end data messages 150
  • 181. CRUD start SAF create commit message put / commit SAF update end data messages 150
  • 182. CRUD start SAF create commit message put / commit SAF update end data messages 151
  • 183. CRUD start SAF create commit message put / commit SAF update end data messages 151
  • 184. CRUD start SAF create commit message put / commit SAF update end data messages messages 151
  • 185. CRUD start SAF create commit message put / commit SAF update ☺ end data messages messages 151
  • 186. CRUD start SAF create commit message put / commit Recoverable SAF update ☺ end data messages messages 151
  • 187. CRUD start SAF create commit message put / commit SAF update ☺ end data messages messages 151
  • 188. CRUD start SAF create commit message put / commit SAF update ☺ end data messages messages 151
  • 189. CRUD start SAF create commit message put / commit SAF update end data messages 152
  • 190. CRUD start SAF create commit message put / commit SAF update end data messages 152
  • 191. CRUD start SAF create commit message put / commit SAF update end data messages 153
  • 192. CRUD start SAF create commit message put / commit SAF update end data messages messages 153
  • 193. CRUD start SAF create commit message put / commit SAF update ☺ end data messages messages 153
  • 194. CRUD start SAF create commit message put / commit Duplicated SAF update ☺ end data messages messages 153
  • 195. CRUD start SAF create commit message put / commit SAF update ☺ end data messages messages 153
  • 196. CRUD start SAF create commit message put / commit SAF update ☺ end data messages messages 153
  • 197. Ensure Atomicity of application transaction and putting message 154
  • 199. Lightweight Robust Simple API Recovery Test support Flexible SAF system design 156
  • 201. • Messages recovery when some troubles happen • Collaboration with Capistrano (2.x) • Test support 158
  • 203. TDD / BDD 160
  • 204. ☺ It makes us feel relieved in developing an application 161
  • 205. On async app. • Test matters also, but .. • Multiple processes communicating via N/W • take time • annoying to setup 162
  • 206. Two ways of testing • Functional test • no N/W communication • fast but restricted • Async test • using N/W communication • slow but close to actual 163
  • 207. Functional test • Provided a queue stub • Executed in memory, quickly 164
  • 208. code sample test code here is against a ‘fictional’ on-line shop application, which has an order action (sync) and payment action (async). 165
  • 209. def test_order post :order, :order => {:item => quot;introduction to AP4Rquot;} assert_response :redirect assert_redirected_to :action => 'index' messages = @controller.ap4r.queued_messages # ... (1) assert_equal 1, messages.keys.size, quot;should have messages in just ONE queuequot; assert messages.key?(quot;queue.async_shop.paymentquot;), quot;queue name is INCORRECTquot; # ... (2) assert_equal 1, messages[quot;queue.async_shop.paymentquot;].size, quot;should have just ONE message for paymentquot; assert_match /order_id=d+/, messages[quot;queue.async_shop.paymentquot;].first[:body], quot;parameter order_id should be included with a numeric valuequot; # ... (3) end 1. get (stubbed)queued messages 2. assert the queue name 3. assert the message content 166
  • 210. functional test rake .. CRUD message put Stub assert assert 167
  • 211. Async test • Get on reality • Test everything, e.g serialization, cooperation. 168
  • 212. code sample test code here is against a ‘fictional’ application. 169
  • 213. [RAILS_ROOT]/test/async/ap4r_test_helper.rb ENV[quot;RAILS_ENVquot;] = quot;testquot; require File.expand_path(File.dirname(__FILE__) + quot;/../../config/environmentquot;) require quot;ap4r/service_handlerquot; ap4r_test_helper = Ap4r::ServiceHandler.new require 'test_help' class Test::Unit::TestCase self.use_transactional_fixtures = false self.use_instantiated_fixtures = false # Add more helper methods to be used by all tests here... cattr_accessor :ap4r_helper def ap4r_helper @@ap4r_helper end def with_services(&block) ap4r_helper.with_services(&block) end end Test::Unit::TestCase.ap4r_helper = ap4r_test_helper 170
  • 214. [RAILS_ROOT]/test/async/async_shop_test.rb require quot;#{File.dirname(__FILE__)}/ap4r_test_helperquot; require 'net/http' class AsyncShopTest < Test::Unit::TestCase def test_http_dispatch ap4r_helper.stop_dispatchers # ... (1) assert_rows_added(Order, 1) { # ... (3) do_order # ... (2) } assert_rows_added(Payment, 1) { # ... (6) ap4r_helper.start_dispatchers # ... (4) ap4r_helper.wait_all_done # ... (5) } end private # Requests to <tt>async_shop/order</tt>. def do_order(item_name = quot;test itemquot;) Net::HTTP.start(quot;localhostquot;, 3000, nil, nil) do |http| http.request_post(quot;/async_shop/orderquot;, quot;order[item]=#{item_name}quot;) do |res| #nop end end end def assert_rows_added(model, rows) rows_before = model.count yield rows_after = model.count assert_equal rows, rows_after - rows_before, quot;table '#{model.table_name}' should count up by #{rows}quot; end end 171
  • 215. stop dispatcher threads 1. request to Rails with HTTP POST 2. assert one row added to orders table 3. start dispatcher threads 4. wait for async action is completed 5. assert one row added to payments table 6. 172
  • 216. async test rake .. service control HTTP CRUD message put assert HTTP CRUD assert 173
  • 217. Summary • Two test methods. • Functional test • Async test • It makes us feel relieved to develop an application 174
  • 219. AP4R is .. 176
  • 220. Lightweight and Robust 177
  • 221. Lightweight Robust Simple API Recovery Test support Flexible SAF system design 178
  • 222. • Messaging with simple API, simple configuration • Seamless collaboration with Rails • Flexible system design 179
  • 223. • Automatically invocation of async. processing by dispatcher • Guaranteed delivery by SAF • Test support • Recovery and deployment 180
  • 225. Smooth operation ver.0.3.x ☑ Daemonize ☑ URL-rewrite filter ☑ DLQ / SAF recovery □ Protocols: Stomp, HTTP 182
  • 226. Monitoring ver.0.4.x □ Coordinate with Cacti, ZABBIX, etc. □ Many AP4R processes □ Interactive management tool 183
  • 227. Step to large scale ver.0.5.x □ Dynamic configuration □ Automatic recovery □ Long run 24/7 184
  • 228. Others □ Security ☑ Application testing support □ Blocking queues □ Ruby off Rails 185
  • 229. AP4R@RubyForge • wiki: http://ap4r.rubyforge.org/wiki/wiki.pl?HomePage • source: svn co http://ap4r.rubyforge.org/svn/trunk/ap4r • ML: http://rubyforge.org/mailman/listinfo/ap4r-user Your patches are welcome! Thank you. by Kanican 186
  • 230. Future Architect logo belongs to Future Architect, Inc. Japan. All rights reserved. • Rails logo is trademarks of David Heinemeier Hansson. All rights reserved. • The Ruby logo is copyrighted (c) 2006, Yukihiro Matsumoto. It is released under the terms of the Creative Commons Attribution-ShareAlike 2.5 License. 187