Pattern Oriented Software Architectureã«ã€ããŠ.
ðãœãããŠã§ã¢ã¢ãŒããã¯ã㣠- ãœãããŠã§ã¢éçºã®ããã®ãã¿ãŒã³äœç³»(POSA-1)
- title: ãœãããŠã§ã¢ã¢ãŒããã¯ãã£âãœãããŠã§ã¢éçºã®ããã®ãã¿ãŒã³äœç³»
- url: http://www.amazon.co.jp/exec/obidos/ASIN/4764902834/asakichy-22/
- notes.
- äŒç€Ÿã®å³æžé€šã«ãã£ã.
æ··æ²ããæ§é ãž
è€éã«ãªããã¡ãªãœãããŠã§ã¢ã®æ§é ãæŽçããŠãåå²ããŠçµ±æ²»ãããããã®ãã¿ãŒã³.
Layers
ã¢ããªã±ãŒã·ã§ã³ãè€æ°ã®âå±€âã«åã, ããããç¬ç«ããã¢ãžã¥ãŒã«ãšããŠéçºã»ä¿å®ãã. åå±€ã¯ã€ã³ã¿ãã§ãŒã¹ãå®çŸ©ãã¢ãžã¥ãŒã«åããããœãããŠã§ã¢ã§ãã, ãã¯ãããžãŒã®é²æ©ãèŠæ±ã®å€åã«åãããŠåå±€ãåå¥ã«çœ®æã§ãã.
åå²ãå¿ èŠãªå€§èŠæš¡ãªã·ã¹ãã ãåæ. å°èŠæš¡ã·ã¹ãã ã§ã¯ãããªã.
-
ç¹åŸŽ
- é£æ¥ããªãã¬ã€ã€ãžã®ã¢ã¯ã»ã¹ãçŠæ¢
- çæ¹åã®ã¢ã¯ã»ã¹ãèš±å¯.
-
ã¡ãªãã
- å€æŽãå±æåãããããä¿å®æ§ãåäžãã,
- æœè±¡åºŠã®äœãäžäœã¬ã€ã€ã¯, ããŸããŸãªã·ã¹ãã ã§åå©çšã§ããå¯èœæ§ããã
- ã¬ã€ã€éã®ããåããæšæºåãããŠããå Žå, ã¬ã€ã€ã亀æããããšã容æã«ãªã
Pipes and Filters
lackboard
åæ£ã·ã¹ãã
åæ£ã·ã¹ãã ãéçºããäžã§æå¹ãªãã¿ãŒã³.
Broker
察話åã·ã¹ãã
人ãšã³ã³ãã¥ãŒã¿ã®å¯Ÿè©± (ã¯ã©ã€ã¢ã³ããšã·ã¹ãã ã®å¯Ÿè©±) ãæäŸããã·ã¹ãã ã§æå¹ãªãã¿ãŒã³
Model-View-Controller
Presentation-Abstraction-Control
é©ååã·ã¹ãã
ç°å¢ã®å€åãæ©èœèŠæ±ã®å€åã«ããäžæ žæ©èœãžã®åœ±é¿ãæããããã«æå¹ãªãã¿ãŒã³.
Microkernel
Reflection
References
- POSA ã®ã¢ãŒããã¯ãã£ãã¿ãŒã³ - Strategic Choice
- 第 2 å ã¢ãŒããã¯ãã£ãŒãã¿ãŒã³ãšã¯äœã | Think IT
ðPattern-Oriented Software Architecture: Patterns for Concurrent and Networked Objects(POSA-2)
Doug å ç, 枟身ã®èäœ! ãªãã® PDF 矀.
ãšãŠãåèã«ãªããªã³ã¯. POSA2.
Service Access and Configuration Patterns
Wrapper Facade
Wrapper Facade Pattern ã«ã€ããŠèª¿ã¹ãŠã¿ããŸãšã | Futurismo
ãœã±ãããªã©ã® OS ã«äŸåãããã㪠native methods ã«å¯ŸããŠã©ãããŒã©ã€ãã©ãªãäœæããããš.
encapsulate low-level functions and data
structures with object-oriented (OO) class interfaces.
以äžã®ã¡ãªããããã.
- Non-OOP èšèªã OOP ã§å©çšã§ããã (Type-safe I/F)
- OS äŸåããªããªã£ãã, (Portable)
- ã³ã³ãã€ã«æã«ãšã©ãŒããã§ãã¯ããæ©èœãäœã蟌ãã ãããŠ,API error-prone (誀ããã¡ãª) ãé²ã.
Facade ã Bridge ãšç°ãªã, èã, Light weight ãªå®è£ ã§ãªãŒããããããªãããšãç¹åŸŽ.
coursera ã® posa è¬çŸ©ã§åºãŠãããã¿ãŒã³. Doug æ° ã®è«æ.
èšèªã¬ãã«ã§ãµããŒããããŠããããšãå€ã? Ruby ã® Socket Library ãããäŸ. bind ã listen ã TCPServer ã¡ãœããã§é ããŠãã.
server = TCPServer.new (4481)
# =>
server = Socket.new (:INET, :STREAM)
addr = Socket.pack_sockaddr_in (4481, "0.0.0.0")
server.bind (addr)
server.listen (5)
Component Configurator
Interceptor
Extension Interface
Event Handling Patterns
Reactor (Evented)
Reactor Pattern ã«ã€ããŠèª¿ã¹ãŠã¿ããŸãšã | Futurismo
ã€ãã³ãé§åã®ããã®ãã¿ãŒã³. åæçãªã€ãã³ãåŠç.
The reactor design pattern is an event handling pattern
for handling service requests delivered concurrently
to a service handler by one or more inputs.
Networking ã§å©çšããã Reactor ã¯, select ã䜿ã£ãç矩㮠Reactor Pattern.
-
ç¹åŸŽ
ã€ãã³ã (å ¥åããŒã¿) ã,åŠçãç¶æ ãè¡šããã³ãã© (ã¡ãœãã or ãµãã¯ã©ã¹) ã«ãã£ã¹ããã (çµã³ã€ãã) ãã.
ãã³ãã©ããšã«è²¬åãåå²ã§ããã®ã§ OOP åã.
EventMachine 㯠Reactor ãã¿ãŒã³ã®é«æ§èœãªå®è£ ã.
Android ã¯ç¶æ ããšã«ãã³ãã©ãåŒã³åºããã.
- onCreate ()
- onResume ()
- onDestory ()
Spring Framework ã§ã¯, GET ã POST ã® HTTP request ã¯, ãããã察å¿ããã¡ãœããã«ã³ãŒã«ããã¯ããã.
-
Structure
- Resources: å ¥åããŒã¿
- Synchronous Event Demultiplexer:å
¥åããŒã¿ãæŸãããã®ã€ãã³ãã«ãŒã.
- ã·ã³ã°ã«ã¹ã¬ãã㧠loop ããŠããããšãç¹åŸŽ (Synchronous).
- Dispatcher: ãã³ãã©ã管çãã. Demultiplexer ããéç¥ãåããã,
- Resource ã Handler ã« Dispatch ãã (select ãªã©)
- Handler: Resource ã«é¢é£ä»ããããåŠç.
-
References
Proactor
éåæãªã€ãã³ãåŠç.
POSIX ã® aio ãå©çšããŠå®çŸãã.
éåæã« I/O æäœãå®æœããŠ, çµäºæã«ã¯ã³ãŒã«ããã¯ã§éç¥ãåãåã. Non-Blocking.
-
Reactor ãš Proactor ã®éã
ããã ããšãã¿.
æ¥æ¬èªã®è§£èª¬: C++ vs. Java vs. C#ã®ãããã¯ãŒã¯ããã©ãŒãã³ã¹æ¯èŒ - äºäž
Reactor ãã¿ãŒã³
select (2) or poll (2) ã§ãœã±ããã®ç£èŠãããŠ, non-blocking ãªrecv (2), send (2) ã§éåä¿¡ããŸã.
ãœã±ãããèªã¿æžãã§ããããã«ãªããŸã§ã«ãŒãã«ã§åŸ æ©ããŠ, èªã¿æžãã§ããããã«ãªããšãŠãŒã¶ã¢ããªã«å¶åŸ¡ãæ¥ãŸã. ãŠãŒã¶ã¢ããªã¯recv ã§èªã¿èŸŒãã ããŒã¿ããããã¡ã«ã³ã㌠(èªã¿èŸŒã¿æ) ããã, ãããã¡ã«ããŒã¿ãæžã蟌ã㧠send ãåŒã³ãŸã. å®éã®ãããã¯ãŒã¯äžãžã®ããŒã¿éåä¿¡ã¯, ã«ãŒãã«ã®ä»äºã§ã.
Proactor ãã¿ãŒã³
éåæ IO ã® API (aio_ã® prefix ã®ä»ãã API) ã§éåä¿¡ããŸã. ãããã¯ãŒã¯ã®éåä¿¡ãå®äºããæç¹ã§, ã«ãŒãã«ãããŠãŒã¶ã¢ããªã«å¶åŸ¡ãæ¥ãŸã. èªã¿èŸŒã¿ã®å Žå, ãããã¡ã«èªã¿èŸŒã¿ããŒã¿ãæ¢ã«å ¥ã£ãŠããã®ã§, ãŠãŒã¶ã¢ããªã¯ããã䜿ããŸã.
http://subtech.g.hatena.ne.jp/mala/20090920/1253447692
ãã¡ã€ã«ãã£ã¹ã¯ãªãã¿ã«ããŒã¿ãæžã蟌ãå Žåã ãš
- Reactor ãã¿ãŒã³ã§ã¯ã writable ã«ãªãã®ãåŸ ã€, æžã蟌ããã ãæžã蟌ãããšããã®ãå šãŠã®æžã蟌ã¿ãçµãããŸã§ç¹°ãè¿ããŸã.
- Proactor ãã¿ãŒã³ã§ã¯, ã«ãŒãã«ã«è»¢éãä»»ããŠ, 転éãå®äºããæç¹ã§ã€ãã³ããçºçããŸã.
極端ãªè©±, 1byte ãã€ããããŒã¿ãéããªãããã€ã¹ããã£ããšããŠ
- Reactor ãã¿ãŒã³ã§ 1MB éãããšããå Žå, 100 äžå (100 äž * n) ã®ã³ã³ããã¹ãã¹ã€ãããçºçãã.
- Proactor ãã¿ãŒã³ã®å Žåã¯, ã«ãŒãã«ã« 1MB ã®ããŒã¿ãéã£ãŠãããŠ, ãšäŸé ŒããŠçµãã£ãããŠãŒã¶ãŒã¢ãŒãã«åŠçãæ»ã. ã³ã³ããã¹ãã¹ã€ããã¯æå°éã§æžã¿ãŸã.
ã©ã¡ããåªããŠããã?
- ãŠãŒã¶ãŒã¢ãŒããšã«ãŒãã«ã¢ãŒãã®ã³ã³ããã¹ãã¹ã€ããã®ã³ã¹ã.
- å ããŠ: ã€ãã³ãé§åã¢ãã«ã§æžããŠããå Žåã¯, é¢æ°åŒã³åºãã®ã³ã¹ã.
- å ããŠ: ã¹ã¬ããã¢ãã«ã§æžããŠããå Žåã¯, ã¹ã¬ãã or 軜éã¹ã¬ããã®ã³ã³ããã¹ãã¹ã€ããã®ã³ã¹ã.
ã, çºçããããšã«ãªããŸã. ãã®ã³ã¹ããç¡èŠã§ããªãã»ã©å€§ããå Žå, Proactor ãã¿ãŒã³ã®åªäœæ§ã倧ãããªã, ãšããããšã«ãªãã§ããã.
- StackOverflow: java - reactor vs proactor - Stack Overflow
- ãããããã PDF paper: Event-driven I/O paper - Marcâs Blog
The main difference between reactor and proactor is the way they do the actual write/read.
- the reactor is only being signalled when the socket is ready to write/read and then does.the reading/writing itself in a synchronous manor
- the proactor will use an asynchronous I/O call to the operating system and only supply the buffers to read from/write to.read from/write to.
Asynchronous Completion Token
Acceptor-Connector
éä¿¡ã®åæååŠçãšå®éã®åŠçãåé¢ããããšã§, æ§é ãæŽçãããã¿ãŒã³.
Reactor Pattern ã«ãããŠ, Handler ãš Reactor ã®ä»²ä»ãè¡ã. Handler ã« Dispatch ããåã«, äžé£ã®æç¶ããå¿ èŠãªå Žåã«ã¯,
- Acceptor ã Handler ã«å¯ŸããŠæç¶ããå®æœããŠãã (Accept)
- Reactor ãã Handler ãžã® Dispatch ãããã (Connect)
Acceptor ããµãŒãåŽã®ä»²ä»è , Connector ãã¯ã©ã€ã¢ã³ãåŽã®ä»²ä»è .
ã¯ã©ã¹å³çã«ã¯,EventHandler ã®ãµãã¯ã©ã¹ã« Handler ã Acceptor, Connector ããã.
EventHandler
- CifsAcceptor
- negotiate
- session
- CifsHandler
- read
- write
- CifsConnector
- negotiate
- session
Synchronization Patterns
Scoped Locking
ã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ãŠ lock ããŠ,ãã³ã³ã¹ãã©ã¯ã¿ã§ Unlock ãã.
Strategized Locking
Thread-Safe Interface
Double-checked locking
ããã¯ã®ååŸã«ããããªãŒãããããåæžããããã®ææ³. ãŸããã¹ã¬ããã»ãŒãã§ãªãæ¹æ³ã§ãããã¯ãã³ããã調ã¹ãŠ, ãããæåãããå®éã®ããã¯ãè©Šã¿ã.
Concurrency Patterns
Active Object (Actor)
ã¡ãœããã®åŒã³åºããšã¡ãœããã®å®éã®å®è¡ãåé¢ããããšã§äžŠè¡æ§ãå°å ¥ãã. åãªããžã§ã¯ãã¯å©çšè ããã®èŠæ±ã管çããããã®ã¡ãã»ãŒãžãã¥ãŒãšã¹ã±ãžã¥ãŒã©ãæã€.
å€éšã® Client ã¹ã¬ããããéåæã«ã¡ãã»ãŒãžãåãåã£ãŠã, èªååºæã® Active Object ã¹ã¬ããã§, èªåã®éœåã®ããã¿ã€ãã³ã°ã§åŠçãå®è¡ããããå Žåã«å©çšãã.
èµ·å (invocation) ãšå®è¡ (execution) ã®åé¢.
Active Object defines units of concurrency as service requests on components & runs service requests on a component in a different thread from the requesting client thread.
-
ä»ã®ãã¿ãŒã³ãšã®é¢ä¿
Acceptor-Connector / Reactor
Acceptor-Connector Pattern ã«ããã Handler éšåãã¹ã¬ããåããã°ãã. (i.e. Thread per connection) Reactor ã® Minor Change ã§å®çŸã§ãã.
Half-Sync/Half-Async
Active Object ã¯ã¹ã¬ãã/ ã¹ã¬ãããåé¢ãã. Half-Sync/Half-Async ã¯, éåæããã»ã¹ãšåæããã»ã¹ãåé¢ãã.
-
Sample
Java ã®ãµã³ãã«
Ruby ã®ãµã³ãã«
Monitor Object
æä»çã«å®è¡ããªããã°ãªããªãã¡ãœãã矀ãæã€ãªããžã§ã¯ããã¹ã¬ããã»ãŒãã«å©çšã§ããããã«ããããã®æ©æ§. Java ã¯ãããèšèªã¬ãã«ã§ãµããŒãããŠãã.
- javax.management.monitor (Java Platform SE 6)
- Monitor (synchronization) - Wikipedia, the free encyclopedia
- ã¹ã¬ããã®æä»å¶åŸ¡
Half-Sync/Half-Async Pattern ãšçµã¿åãããŠå©çšããããšã§, busy ã®å¶åŸ¡ãæãªæã®é床ãªè² è·ãé¿ãã.
Half-Sync/Half-Async
éåæãµãŒãã¹ãšåæãµãŒãã¹ãåé¢ãã. éåæã¬ã€ã€ãšåæã¬ã€ã€ã¯ãã¥ãŒã§ã€ãªãã£ãŠãã.
éåæåŠçãšåæåŠçãå ±åãããŠ, æ§é ãã·ã³ãã«ã«ã§ãã.
The Half-Sync/Half-Async pattern decouples async & sync service processing in concurrent systems, to simplify programming without unduly reducing performance.
-
Example of Networking Programming
ãã®ãã¿ãŒã³ã¯ OS ã GUI Framework ã§åºãå©çšãããŠãã.
OS äžã§åããããã¯ãŒã¯ã¯ã©ã€ã¢ã³ãã¯,ãœã±ããã« read/write ãã. ãã®ãšã, ãœã±ããããã¥ãŒã«ãªã£ãŠ, Kernel ãç©ç NIC ãšãããšãããã.
- User-Level Processes
- Sync User Process 1
- Sync User Process 2
- Sync User Process 3
- Socket Layer
- Socket Queues
- BSD UNIX Kernel
- Async Protocol Processing
- NIC
- User-Level Processes
-
Netty ã«ããå®è£
å®å šã«ãããããç§ã®å®è£ ?
Leader/Followers
Preforking or Thread Pool åç §.
äºåã« ã¹ã¬ãããäœã£ãŠããã®ã§, ãªãŒãããããå°ãã.
Thread-specific storage
éçå€æ°ã»ã°ããŒãã«å€æ°ã®ããã«æ±ãããã¹ã¬ããããšã«ç°ãªãå 容ãæ ŒçŽã§ããã¡ã¢ãªé åãæäŸãã.
POSA-3
POSA-4
POSA-5
Network Architecture Patterns
pWorking with TCP Sockets ãã.
Serial
- advantage
- Structure is simple.
- Resource usage is simple.
- disadvantage
- No concurrency.
Process per connection
connection ããšã« åããã»ã¹ãèµ·åãã. connection ã accept ããããšã«ããã»ã¹ãçæãã.
- advantage
- simple
- less overhead
- disadvantage
- Unix system éå®
- ããã»ã¹æ°ã«ã¯éçããã
Thread per connection
connection ããšã« ã¹ã¬ãããèµ·åãã. connection ã accept ããããšã«ã¹ã¬ãããçæãã.
- advantage
- process per connection ããã äœ resource, overhead
- disadvantage
- ã¹ã¬ããæ°ã«ã¯éçããã
Preforking
connection ããšã« åããã»ã¹ãèµ·åãã. ããããã process ãå¿ èŠæ°èµ·åããŠãã, accept ããããã®ããã»ã¹ã«åŠçãå®æœããã.
- advantage
- äºåã«ããã»ã¹ãèµ·åããŠããã®ã§, accept æã® overhead ããªã.
- ã¡ã¢ãªã®æä»ãæèããå¿ èŠããªã.
- disadvantage
- ã¹ã¬ããã«æ¯ã¹ãŠããå€ãã®ã¡ã¢ãªãå©çšãã.
Thread Pool
connection ããšã« ã¹ã¬ãããèµ·åãã. ããããã ã¹ã¬ãã ãå¿ èŠæ°èµ·åããŠãã, accept ããããã®ã¹ã¬ããã«åŠçãå®æœããã.
Evented (Reactor)
ç¹åŸŽ
- ãã¹ãŠã®åŠçãã·ã³ã°ã«ã¹ã¬ããã§å®æœãã.
- ãã«ãã¹ã¬ãããå©çšããªããŠã, éåæåŠçãããã.
- ã¹ã¬ãããããã»ã¹æ°ã®å¶éãªãã«, ã¯ã©ã€ã¢ã³ãããã®èŠæ±ã«çããããšãã§ãã.
å®è£ æ¹æ³
- ãœã±ããã select ã§ç£èŠãã. èªã¿åãå¯èœ, æžã蟌ã¿å¯èœãªãœã±ããã®ã¿ã«å¯ŸããŠåŠçãå®æœãã.
- é ãåç·ããããšãã«, ãã®åç·ã«åŒãããã㊠Reactor ãä»ã®åŠçãã§ããªã. ãã¹ãŠã®åŠçã Blocking ããã. ãããªãšãã¯, non-blocking write ãå©çšãã.
sample
-
synchronized
hosts.each do |host| sock = TCPSocket.new (host, 80) sock.write (request) sock.read sock.close end
-
threads
threads = hosts.map do |host| Thread.new (host) do |h| sock = TCPSocket.new (h, 80) sock.write (request) sock.read sock.close end end threads.each{|t| t.join}
-
reactor
write_socks = hosts.map do |host| TCPSocket.new (host, 80) end read_socks = [] # handler write_proc = lambda{|sock| sock.write (request) } # handler read_proc = lambda{|sock| sock.read sock.close } # Reactor until (write_socks + read_socks).empty? # Demultiplexer r_socks, w_socks, e_socks = IO.select (read_socks, write_socks) # Dispatcher if ws = w_socks.first write_proc.call (ws) read_socks << ws write_socks.delete (ws) end # Dispatcher if rs = r_socks.first read_proc.call (rs) read_socks.delete (rs) end end
ðRelated
- ðPrompt Engineering for ChatGPT - Jules White, Coursera, 2023幎ã®ä»äº. ããã³ãããšã³ãžãã¢ãªã³ã°ãã¿ãŒã³.
- up: ðãœãããŠã§ã¢èšèš