SlideShare une entreprise Scribd logo
1  sur  35
Télécharger pour lire hors ligne
:
Thrift & PasteScript
     BPUG, Sep, 2010
• IaaS - Infrastructure as a Service
• PaaS - Platform as a Service
• SaaS - Software as a Service
•
•
•
•
•   /
Service
HTTP + web.py
import web                             import urllib

urls = ('/add', 'add')                 def add(a, b):
                                           f = urllib.urlopen('http://
class add:                             calculator.services.douban.com/add?a=%s&b=
    def GET(self):                     %s' % (a, b))
        i = web.input()                    r = f.read()
        r = int(i.a) + int(i.b)            return int(r)
        return str(r)

app = web.application(urls, globals)

if __name__ == '__main__':
    app.run()
•
    • JSON
• HTTP       overhead
Thrift
http://incubator.apache.org/thrift/
Thrift
•
    •   C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk, OCaml


•
    •   struct, list, set, map

•
•            oneway calling
•            RPC
Thrift Example
struct UserProfile {
  1: i32 uid,
                                                              class UserStorageHandler : virtual public UserStorageIf {
  2: string name,
                                                               public:
  3: string blurb
                                                                UserStorageHandler() {
}
                                                                  // Your initialization goes here
service UserStorage {
                                                                }
  void store(1: UserProfile user),
  UserProfile retrieve(1: i32 uid)
                                                                void store(const UserProfile& user) {
}
                                                                  // Your implementation goes here
                                                                  printf("storen");
                                                                }

                                                                void retrieve(UserProfile& _return, const int32_t uid) {
# Make an object                                                  // Your implementation goes here
up = UserProfile(uid=1,                                           printf("retrieven");
                 name="Mark Slee",                              }
                 blurb="I'll find something to put here.")    };

# Talk to a server via TCP sockets, using a binary protocol   int main(int argc, char **argv) {
transport = TSocket.TSocket("localhost", 9090)                  int port = 9090;
transport.open()                                                shared_ptr<UserStorageHandler> handler(new UserStorageHandler());
protocol = TBinaryProtocol.TBinaryProtocol(transport)           shared_ptr<TProcessor> processor(new UserStorageProcessor(handler));
                                                                shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
# Use the service we already defined                            shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFac
service = UserStorage.Client(protocol)                          shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory(
service.store(up)                                               TSimpleServer server(processor, serverTransport, transportFactory, proto
                                                                server.serve();
# Retrieve something as well                                    return 0;
up2 = service.retrieve(2)                                     }
Thrift
thrift package   generated code

   Protocol         Processor
   (binary)        (dispatcher)


  Transport         Handler
   (socket)        (app code)
Thrift

•
•
•
•
•
•
PasteScript
http://pythonpaste.org/script/
Paste

• WSGI
•
  • Paste
  • PasteScript
  • PasteDeploy
PasteScript


• paster serve
• templates
paster serve
• paster serve --reload --monitor-restart
  development.ini
            [server:main]
            use = egg:Paste#http
            host = 0.0.0.0
            port = 5000

            [app:main]
            use = egg:MyWSGIApp

            # Logging configuration
            [loggers]
            keys = root, access_log
            ...
Thrift
server         app

Protocol     Processor
(binary)    (dispatcher)


Transport    Handler
 (socket)   (app code)
paster serve
• paster serve --reload --monitor-restart
  development.ini
        [server:main]
        use = egg:DoubanService#thread_pool
        port = 9090
        pool_size = 10

        [app:main]
        use = egg:CalculatorServer

        # Logging configuration
        [loggers]
        keys = root, access_log
        ...
setuptools entry points
DoubanService/setup.py:
 entry_points = """
 [paste.server_runner]
 thread_pool = doubanservice.server:thread_pool_server_runner
 """



CalculatorServer/setup.py:
 entry_points = """
 [paste.app_factory]
 main = calculator_server.makeapp:make_app
 """
app

from .gen.calculator import Iface, Processor
from .app import Handler

def make_app(global_config, **local_conf):
    handler = Handler()
    processor = Processor(handler)
    return processor
server runner
def thread_pool_server_runner(app, global_conf, **kwargs):
    for name in ['port', 'pool_size']:
        if name in kwargs:
            kwargs[name] = int(kwargs[name])
    pool_size = kwargs.pop('pool_size')
    host = kwargs.pop('host', '0.0.0.0')
    transport = TSocket.TServerSocket(**kwargs)
    transport.host = host
    tfactory = TTransport.TBufferedTransportFactory()
    pfactory = TBinaryProtocol.TBinaryProtocolFactory()
    server = ThreadPoolServer(app, transport, tfactory, pfactory)
    if pool_size:
        server.threads = pool_size

    server.serve()
•     (paster serve)
•   ([server:main] use)
•
•                 (--reload)
•   ([loggers])
Paste Template
DoubanService/setup.py:
entry_points = """
[paste.server_runner]
thread_pool = doubanservice.server:thread_pool_server_runner

[paste.paster_create_template]
doubanservice = doubanservice.templates:DoubanServiceTemplate
doubanservice_server_py = doubanservice.templates:ServerPyTemplate
doubanservice_client_py = doubanservice.templates:ClientPyTemplate
"""




   paster create -t doubanservice calculator
doubanservice template
class DoubanServiceTemplate(paste.script.templates.Template):
    _template_dir = 'doubanservice'
    summary = "A DoubanService project"

   def post(self, command, output_dir, vars):
       for filename in ['gen', 'create-server', 'create-client']:
           os.chmod(os.path.join(output_dir, filename), 0755)


doubanservice/templates/doubanservice/
├── +package+.thrift_tmpl
├── create-client_tmpl
├── create-server_tmpl
                                        vi calculator.thrift
└── gen_tmpl                            ./create-server py
                                        ./create-client py
                                        ./gen
server_py template
doubanservice/templates/server-py/
├── +package+
│   ├── __init__.py
│   ├── app.py_tmpl
│   └── makeapp.py_tmpl
├── development.ini_tmpl
├── gen_tmpl
├── production.ini_tmpl
├── remote_tmpl
├── scripts
│   └── censor-server-py
├── serve                   vi calculator_server/app.py
├── setup.cfg               ./serve
├── setup.py_tmpl
└── tests                   ./remote add 1 2
client_py template
 doubanservice/templates/client-py
 ├── +package+
 │   ├── __init__.py           class Client(BaseClient):
 │   └── client.py_tmpl            __metaclass__ = ClientMetaClass
 ├── gen_tmpl                      service_name = '${service}'
 ├── setup.py_tmpl                 thrift_module = ${service}_genmod
 └── tests                         port = 9090
                                   connect_timeout = 1000
                                   read_timeout = 5000

                              ${service} = Client()


from calculator_client import calculator
print calculator.add(1, 2)
Demo
a calculate service
A New OpenSource Project...
OneRing
Build Desktop Applications Using Web Technology
    http://code.google.com/p/onering-desktop/
•       Web
    •         HTML5+CSS3               /
    •         Javascript           /
    •     AJAX
•
    •   Qt (mac, windows, linux)
    •   Cairo (windows, linux)
    •   WebKit Framework (mac)
•
    •   C API DLL
    •   Python - WSGI
#!/usr/bin/env python
import json
import web
import onering

urls = (
    '/init', 'init',
    '/', 'index',
)

class init:
    def GET(self):
        web.header('Content-Type', 'application/json')
        return json.dumps({'width': 400, 'height': 300, 'url': '/'})

class index:
    def GET(self):
        web.header('Content-Type', 'text/html')
        return """<html>
<head><script type="text/javascript" src="onering://onering/onering.js"></script></head>
<body>
<p>Hello, world!</p>
<button onclick="javascript:ONERING.exit()">Exit</button>
</body></html>"""

app = web.application(urls, globals())

if __name__ == '__main__':
    onering.register_wsgi_app("demo", app.wsgifunc())
    onering.loop("demo")
Join Us If You Know...
•   C++ / C / Objective-C / Python
•   Qt / win32 / Cocoa / GTK
•   WebKit / Gecko
•   Javascript / HTML5
•   Python C API / py2exe / py2app
•              C
•   Win/Mac/Linux
•
•
•   HTML5
•
Thanks
 Q &A

Contenu connexe

Tendances

AnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time webAnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time webclkao
 
Using ngx_lua in UPYUN
Using ngx_lua in UPYUNUsing ngx_lua in UPYUN
Using ngx_lua in UPYUNCong Zhang
 
RestMQ - HTTP/Redis based Message Queue
RestMQ - HTTP/Redis based Message QueueRestMQ - HTTP/Redis based Message Queue
RestMQ - HTTP/Redis based Message QueueGleicon Moraes
 
DBD::Gofer 200809
DBD::Gofer 200809DBD::Gofer 200809
DBD::Gofer 200809Tim Bunce
 
Streams are Awesome - (Node.js) TimesOpen Sep 2012
Streams are Awesome - (Node.js) TimesOpen Sep 2012 Streams are Awesome - (Node.js) TimesOpen Sep 2012
Streams are Awesome - (Node.js) TimesOpen Sep 2012 Tom Croucher
 
Building a High-Performance Distributed Task Queue on MongoDB
Building a High-Performance Distributed Task Queue on MongoDBBuilding a High-Performance Distributed Task Queue on MongoDB
Building a High-Performance Distributed Task Queue on MongoDBMongoDB
 
Annotation processing and code gen
Annotation processing and code genAnnotation processing and code gen
Annotation processing and code genkoji lin
 
Php on the Web and Desktop
Php on the Web and DesktopPhp on the Web and Desktop
Php on the Web and DesktopElizabeth Smith
 
Integrating icinga2 and the HashiCorp suite
Integrating icinga2 and the HashiCorp suiteIntegrating icinga2 and the HashiCorp suite
Integrating icinga2 and the HashiCorp suiteBram Vogelaar
 
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)ngotogenome
 
Clojure and the Web
Clojure and the WebClojure and the Web
Clojure and the Webnickmbailey
 
PECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life betterPECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life betterZendCon
 
A Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsA Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsMark Baker
 
Reactive Access to MongoDB from Java 8
Reactive Access to MongoDB from Java 8Reactive Access to MongoDB from Java 8
Reactive Access to MongoDB from Java 8Hermann Hueck
 
POCO C++ Libraries Intro and Overview
POCO C++ Libraries Intro and OverviewPOCO C++ Libraries Intro and Overview
POCO C++ Libraries Intro and OverviewGünter Obiltschnig
 
Trading with opensource tools, two years later
Trading with opensource tools, two years laterTrading with opensource tools, two years later
Trading with opensource tools, two years laterclkao
 

Tendances (20)

AnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time webAnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time web
 
Using ngx_lua in UPYUN
Using ngx_lua in UPYUNUsing ngx_lua in UPYUN
Using ngx_lua in UPYUN
 
RestMQ - HTTP/Redis based Message Queue
RestMQ - HTTP/Redis based Message QueueRestMQ - HTTP/Redis based Message Queue
RestMQ - HTTP/Redis based Message Queue
 
DBD::Gofer 200809
DBD::Gofer 200809DBD::Gofer 200809
DBD::Gofer 200809
 
Streams are Awesome - (Node.js) TimesOpen Sep 2012
Streams are Awesome - (Node.js) TimesOpen Sep 2012 Streams are Awesome - (Node.js) TimesOpen Sep 2012
Streams are Awesome - (Node.js) TimesOpen Sep 2012
 
Building a High-Performance Distributed Task Queue on MongoDB
Building a High-Performance Distributed Task Queue on MongoDBBuilding a High-Performance Distributed Task Queue on MongoDB
Building a High-Performance Distributed Task Queue on MongoDB
 
Annotation processing and code gen
Annotation processing and code genAnnotation processing and code gen
Annotation processing and code gen
 
Beyond Phoenix
Beyond PhoenixBeyond Phoenix
Beyond Phoenix
 
Node.js in production
Node.js in productionNode.js in production
Node.js in production
 
Php on the Web and Desktop
Php on the Web and DesktopPhp on the Web and Desktop
Php on the Web and Desktop
 
Follow the White Rabbit - Message Queues with PHP
Follow the White Rabbit - Message Queues with PHPFollow the White Rabbit - Message Queues with PHP
Follow the White Rabbit - Message Queues with PHP
 
Integrating icinga2 and the HashiCorp suite
Integrating icinga2 and the HashiCorp suiteIntegrating icinga2 and the HashiCorp suite
Integrating icinga2 and the HashiCorp suite
 
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)
Running Ruby on Solaris (RubyKaigi 2015, 12/Dec/2015)
 
Clojure and the Web
Clojure and the WebClojure and the Web
Clojure and the Web
 
PECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life betterPECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life better
 
A Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsA Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP Generators
 
Reactive Access to MongoDB from Java 8
Reactive Access to MongoDB from Java 8Reactive Access to MongoDB from Java 8
Reactive Access to MongoDB from Java 8
 
Return of c++
Return of c++Return of c++
Return of c++
 
POCO C++ Libraries Intro and Overview
POCO C++ Libraries Intro and OverviewPOCO C++ Libraries Intro and Overview
POCO C++ Libraries Intro and Overview
 
Trading with opensource tools, two years later
Trading with opensource tools, two years laterTrading with opensource tools, two years later
Trading with opensource tools, two years later
 

Similaire à 服务框架: Thrift & PasteScript

GDG Devfest 2019 - Build go kit microservices at kubernetes with ease
GDG Devfest 2019 - Build go kit microservices at kubernetes with easeGDG Devfest 2019 - Build go kit microservices at kubernetes with ease
GDG Devfest 2019 - Build go kit microservices at kubernetes with easeKAI CHU CHUNG
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applicationsTom Croucher
 
How and why i roll my own node.js framework
How and why i roll my own node.js frameworkHow and why i roll my own node.js framework
How and why i roll my own node.js frameworkBen Lin
 
Fun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksFun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksMongoDB
 
Protocol handler in Gecko
Protocol handler in GeckoProtocol handler in Gecko
Protocol handler in GeckoChih-Hsuan Kuo
 
TypeScript for Java Developers
TypeScript for Java DevelopersTypeScript for Java Developers
TypeScript for Java DevelopersYakov Fain
 
Pemrograman Python untuk Pemula
Pemrograman Python untuk PemulaPemrograman Python untuk Pemula
Pemrograman Python untuk PemulaOon Arfiandwi
 
[232] TensorRT를 활용한 딥러닝 Inference 최적화
[232] TensorRT를 활용한 딥러닝 Inference 최적화[232] TensorRT를 활용한 딥러닝 Inference 최적화
[232] TensorRT를 활용한 딥러닝 Inference 최적화NAVER D2
 
[232]TensorRT를 활용한 딥러닝 Inference 최적화
[232]TensorRT를 활용한 딥러닝 Inference 최적화[232]TensorRT를 활용한 딥러닝 Inference 최적화
[232]TensorRT를 활용한 딥러닝 Inference 최적화NAVER D2
 
如何透過 Go-kit 快速搭建微服務架構應用程式實戰
如何透過 Go-kit 快速搭建微服務架構應用程式實戰如何透過 Go-kit 快速搭建微服務架構應用程式實戰
如何透過 Go-kit 快速搭建微服務架構應用程式實戰KAI CHU CHUNG
 
JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?Doug Hawkins
 
Silicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM MechanicsSilicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM MechanicsAzul Systems, Inc.
 
Better Open Source Enterprise C++ Web Services
Better Open Source Enterprise C++ Web ServicesBetter Open Source Enterprise C++ Web Services
Better Open Source Enterprise C++ Web ServicesWSO2
 
Server Side Swift with Swag
Server Side Swift with SwagServer Side Swift with Swag
Server Side Swift with SwagJens Ravens
 
Joe Walker Interactivewebsites Cometand Dwr
Joe Walker Interactivewebsites Cometand DwrJoe Walker Interactivewebsites Cometand Dwr
Joe Walker Interactivewebsites Cometand Dwrdeimos
 
Do you know what your drupal is doing? Observe it!
Do you know what your drupal is doing? Observe it!Do you know what your drupal is doing? Observe it!
Do you know what your drupal is doing? Observe it!Luca Lusso
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsFrancois Zaninotto
 
Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best PracticesYekmer Simsek
 
Nginx + Tornado = 17k req/s
Nginx + Tornado = 17k req/sNginx + Tornado = 17k req/s
Nginx + Tornado = 17k req/smoret1979
 

Similaire à 服务框架: Thrift & PasteScript (20)

GDG Devfest 2019 - Build go kit microservices at kubernetes with ease
GDG Devfest 2019 - Build go kit microservices at kubernetes with easeGDG Devfest 2019 - Build go kit microservices at kubernetes with ease
GDG Devfest 2019 - Build go kit microservices at kubernetes with ease
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applications
 
How and why i roll my own node.js framework
How and why i roll my own node.js frameworkHow and why i roll my own node.js framework
How and why i roll my own node.js framework
 
Fun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksFun Teaching MongoDB New Tricks
Fun Teaching MongoDB New Tricks
 
Apache Thrift
Apache ThriftApache Thrift
Apache Thrift
 
Protocol handler in Gecko
Protocol handler in GeckoProtocol handler in Gecko
Protocol handler in Gecko
 
TypeScript for Java Developers
TypeScript for Java DevelopersTypeScript for Java Developers
TypeScript for Java Developers
 
Pemrograman Python untuk Pemula
Pemrograman Python untuk PemulaPemrograman Python untuk Pemula
Pemrograman Python untuk Pemula
 
[232] TensorRT를 활용한 딥러닝 Inference 최적화
[232] TensorRT를 활용한 딥러닝 Inference 최적화[232] TensorRT를 활용한 딥러닝 Inference 최적화
[232] TensorRT를 활용한 딥러닝 Inference 최적화
 
[232]TensorRT를 활용한 딥러닝 Inference 최적화
[232]TensorRT를 활용한 딥러닝 Inference 최적화[232]TensorRT를 활용한 딥러닝 Inference 최적화
[232]TensorRT를 활용한 딥러닝 Inference 최적화
 
如何透過 Go-kit 快速搭建微服務架構應用程式實戰
如何透過 Go-kit 快速搭建微服務架構應用程式實戰如何透過 Go-kit 快速搭建微服務架構應用程式實戰
如何透過 Go-kit 快速搭建微服務架構應用程式實戰
 
JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?
 
Silicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM MechanicsSilicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM Mechanics
 
Better Open Source Enterprise C++ Web Services
Better Open Source Enterprise C++ Web ServicesBetter Open Source Enterprise C++ Web Services
Better Open Source Enterprise C++ Web Services
 
Server Side Swift with Swag
Server Side Swift with SwagServer Side Swift with Swag
Server Side Swift with Swag
 
Joe Walker Interactivewebsites Cometand Dwr
Joe Walker Interactivewebsites Cometand DwrJoe Walker Interactivewebsites Cometand Dwr
Joe Walker Interactivewebsites Cometand Dwr
 
Do you know what your drupal is doing? Observe it!
Do you know what your drupal is doing? Observe it!Do you know what your drupal is doing? Observe it!
Do you know what your drupal is doing? Observe it!
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node js
 
Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best Practices
 
Nginx + Tornado = 17k req/s
Nginx + Tornado = 17k req/sNginx + Tornado = 17k req/s
Nginx + Tornado = 17k req/s
 

服务框架: Thrift & PasteScript

  • 1. : Thrift & PasteScript BPUG, Sep, 2010
  • 2.
  • 3. • IaaS - Infrastructure as a Service • PaaS - Platform as a Service • SaaS - Software as a Service
  • 6. HTTP + web.py import web import urllib urls = ('/add', 'add') def add(a, b): f = urllib.urlopen('http:// class add: calculator.services.douban.com/add?a=%s&b= def GET(self): %s' % (a, b)) i = web.input() r = f.read() r = int(i.a) + int(i.b) return int(r) return str(r) app = web.application(urls, globals) if __name__ == '__main__': app.run()
  • 7. • JSON • HTTP overhead
  • 9. Thrift • • C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk, OCaml • • struct, list, set, map • • oneway calling • RPC
  • 10. Thrift Example struct UserProfile { 1: i32 uid, class UserStorageHandler : virtual public UserStorageIf { 2: string name, public: 3: string blurb UserStorageHandler() { } // Your initialization goes here service UserStorage { } void store(1: UserProfile user), UserProfile retrieve(1: i32 uid) void store(const UserProfile& user) { } // Your implementation goes here printf("storen"); } void retrieve(UserProfile& _return, const int32_t uid) { # Make an object // Your implementation goes here up = UserProfile(uid=1, printf("retrieven"); name="Mark Slee", } blurb="I'll find something to put here.") }; # Talk to a server via TCP sockets, using a binary protocol int main(int argc, char **argv) { transport = TSocket.TSocket("localhost", 9090) int port = 9090; transport.open() shared_ptr<UserStorageHandler> handler(new UserStorageHandler()); protocol = TBinaryProtocol.TBinaryProtocol(transport) shared_ptr<TProcessor> processor(new UserStorageProcessor(handler)); shared_ptr<TServerTransport> serverTransport(new TServerSocket(port)); # Use the service we already defined shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFac service = UserStorage.Client(protocol) shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory( service.store(up) TSimpleServer server(processor, serverTransport, transportFactory, proto server.serve(); # Retrieve something as well return 0; up2 = service.retrieve(2) }
  • 11. Thrift thrift package generated code Protocol Processor (binary) (dispatcher) Transport Handler (socket) (app code)
  • 15. Paste • WSGI • • Paste • PasteScript • PasteDeploy
  • 17. paster serve • paster serve --reload --monitor-restart development.ini [server:main] use = egg:Paste#http host = 0.0.0.0 port = 5000 [app:main] use = egg:MyWSGIApp # Logging configuration [loggers] keys = root, access_log ...
  • 18. Thrift server app Protocol Processor (binary) (dispatcher) Transport Handler (socket) (app code)
  • 19. paster serve • paster serve --reload --monitor-restart development.ini [server:main] use = egg:DoubanService#thread_pool port = 9090 pool_size = 10 [app:main] use = egg:CalculatorServer # Logging configuration [loggers] keys = root, access_log ...
  • 20. setuptools entry points DoubanService/setup.py: entry_points = """ [paste.server_runner] thread_pool = doubanservice.server:thread_pool_server_runner """ CalculatorServer/setup.py: entry_points = """ [paste.app_factory] main = calculator_server.makeapp:make_app """
  • 21. app from .gen.calculator import Iface, Processor from .app import Handler def make_app(global_config, **local_conf): handler = Handler() processor = Processor(handler) return processor
  • 22. server runner def thread_pool_server_runner(app, global_conf, **kwargs): for name in ['port', 'pool_size']: if name in kwargs: kwargs[name] = int(kwargs[name]) pool_size = kwargs.pop('pool_size') host = kwargs.pop('host', '0.0.0.0') transport = TSocket.TServerSocket(**kwargs) transport.host = host tfactory = TTransport.TBufferedTransportFactory() pfactory = TBinaryProtocol.TBinaryProtocolFactory() server = ThreadPoolServer(app, transport, tfactory, pfactory) if pool_size: server.threads = pool_size server.serve()
  • 23. (paster serve) • ([server:main] use) • • (--reload) • ([loggers])
  • 24. Paste Template DoubanService/setup.py: entry_points = """ [paste.server_runner] thread_pool = doubanservice.server:thread_pool_server_runner [paste.paster_create_template] doubanservice = doubanservice.templates:DoubanServiceTemplate doubanservice_server_py = doubanservice.templates:ServerPyTemplate doubanservice_client_py = doubanservice.templates:ClientPyTemplate """ paster create -t doubanservice calculator
  • 25. doubanservice template class DoubanServiceTemplate(paste.script.templates.Template): _template_dir = 'doubanservice' summary = "A DoubanService project" def post(self, command, output_dir, vars): for filename in ['gen', 'create-server', 'create-client']: os.chmod(os.path.join(output_dir, filename), 0755) doubanservice/templates/doubanservice/ ├── +package+.thrift_tmpl ├── create-client_tmpl ├── create-server_tmpl vi calculator.thrift └── gen_tmpl ./create-server py ./create-client py ./gen
  • 26. server_py template doubanservice/templates/server-py/ ├── +package+ │   ├── __init__.py │   ├── app.py_tmpl │   └── makeapp.py_tmpl ├── development.ini_tmpl ├── gen_tmpl ├── production.ini_tmpl ├── remote_tmpl ├── scripts │   └── censor-server-py ├── serve vi calculator_server/app.py ├── setup.cfg ./serve ├── setup.py_tmpl └── tests ./remote add 1 2
  • 27. client_py template doubanservice/templates/client-py ├── +package+ │   ├── __init__.py class Client(BaseClient): │   └── client.py_tmpl __metaclass__ = ClientMetaClass ├── gen_tmpl service_name = '${service}' ├── setup.py_tmpl thrift_module = ${service}_genmod └── tests port = 9090 connect_timeout = 1000 read_timeout = 5000 ${service} = Client() from calculator_client import calculator print calculator.add(1, 2)
  • 29. A New OpenSource Project...
  • 30. OneRing Build Desktop Applications Using Web Technology http://code.google.com/p/onering-desktop/
  • 31. Web • HTML5+CSS3 / • Javascript / • AJAX • • Qt (mac, windows, linux) • Cairo (windows, linux) • WebKit Framework (mac) • • C API DLL • Python - WSGI
  • 32. #!/usr/bin/env python import json import web import onering urls = ( '/init', 'init', '/', 'index', ) class init: def GET(self): web.header('Content-Type', 'application/json') return json.dumps({'width': 400, 'height': 300, 'url': '/'}) class index: def GET(self): web.header('Content-Type', 'text/html') return """<html> <head><script type="text/javascript" src="onering://onering/onering.js"></script></head> <body> <p>Hello, world!</p> <button onclick="javascript:ONERING.exit()">Exit</button> </body></html>""" app = web.application(urls, globals()) if __name__ == '__main__': onering.register_wsgi_app("demo", app.wsgifunc()) onering.loop("demo")
  • 33. Join Us If You Know... • C++ / C / Objective-C / Python • Qt / win32 / Cocoa / GTK • WebKit / Gecko • Javascript / HTML5 • Python C API / py2exe / py2app • C • Win/Mac/Linux •
  • 34. • • HTML5 •