Transcript
Page 1: Dynamic Code Patterns: Extending Your Applications with Plugins

Dynamic Code Patterns:Extending Your

Applications with PluginsDoug Hellmann – @doughellmann – PyCon 2013

1Saturday, March 16, 13

Page 2: Dynamic Code Patterns: Extending Your Applications with Plugins

What is a “Plugin”?

• Loaded Dynamically

• Extends Core

• Possibly Unknown Source

2Saturday, March 16, 13

Page 3: Dynamic Code Patterns: Extending Your Applications with Plugins

Why Plugins?

• Better API Abstraction

• Reduce Core Dependencies

• Strategy Pattern

• Visitor Pattern

• Indirect Code Contributions

3Saturday, March 16, 13

Page 4: Dynamic Code Patterns: Extending Your Applications with Plugins

• OpenStack Metering

• Measures Clouds

• Varied Billing Requirements

• Deployers Extend and Customize

Ceilometer

4Saturday, March 16, 13

Page 5: Dynamic Code Patterns: Extending Your Applications with Plugins

Ceilometer Design

ComputeImagesVolumesNetworkObjects

NotificationMessage Bus

EventListener

ComputePollsters

CentralPollsters

Collector

Meter DataMessage Bus

5Saturday, March 16, 13

Page 6: Dynamic Code Patterns: Extending Your Applications with Plugins

Ceilometer Design

ComputeImagesVolumesNetworkObjects

NotificationMessage Bus

EventListener

ComputePollsters

CentralPollsters

Collector

Meter DataMessage Bus

5Saturday, March 16, 13

Page 7: Dynamic Code Patterns: Extending Your Applications with Plugins

Ceilometer Design

ComputeImagesVolumesNetworkObjects

NotificationMessage Bus

EventListener

ComputePollsters

CentralPollsters

Collector

Meter DataMessage Bus

5Saturday, March 16, 13

Page 8: Dynamic Code Patterns: Extending Your Applications with Plugins

Ceilometer Design

ComputeImagesVolumesNetworkObjects

NotificationMessage Bus

EventListener

ComputePollsters

CentralPollsters

Collector

Meter DataMessage Bus

5Saturday, March 16, 13

Page 9: Dynamic Code Patterns: Extending Your Applications with Plugins

Ceilometer Design

ComputeImagesVolumesNetworkObjects

NotificationMessage Bus

EventListener

ComputePollsters

CentralPollsters

Collector

Meter DataMessage Bus

5Saturday, March 16, 13

Page 10: Dynamic Code Patterns: Extending Your Applications with Plugins

Ceilometer Design

ComputeImagesVolumesNetworkObjects

NotificationMessage Bus

EventListener

ComputePollsters

CentralPollsters

Collector

Meter DataMessage Bus

5Saturday, March 16, 13

Page 11: Dynamic Code Patterns: Extending Your Applications with Plugins

Ceilometer Design

ComputeImagesVolumesNetworkObjects

NotificationMessage Bus

EventListener

ComputePollsters

CentralPollsters

Collector

Meter DataMessage Bus

5Saturday, March 16, 13

Page 12: Dynamic Code Patterns: Extending Your Applications with Plugins

Ceilometer Design

ComputeImagesVolumesNetworkObjects

NotificationMessage Bus

EventListener

ComputePollsters

CentralPollsters

Collector

Meter DataMessage Bus

5Saturday, March 16, 13

Page 13: Dynamic Code Patterns: Extending Your Applications with Plugins

Ceilometer Design

ComputeImagesVolumesNetworkObjects

NotificationMessage Bus

EventListener

ComputePollsters

CentralPollsters

Collector

Meter DataMessage Bus

5Saturday, March 16, 13

Page 14: Dynamic Code Patterns: Extending Your Applications with Plugins

Ceilometer Plugins

• Message Bus

• Receiving Notifications

• Polling Compute

• Polling Other

• Storage

6Saturday, March 16, 13

Page 15: Dynamic Code Patterns: Extending Your Applications with Plugins

Research• Blogofile

• Sphinx

• Mercurial

• cliff

• virtualenvwrapper

• Nose

• Trac

• Django

• Pyramid

• SQLAlchemy

• Diamond

• Nova

7Saturday, March 16, 13

Page 16: Dynamic Code Patterns: Extending Your Applications with Plugins

Discovery

Explicit Scan

File

Import Reference

Mercurial DiamondBlogofile

Mercurial DjangoPyramidSphinxNova

TracNosecliff

virtualenvwrapper

8Saturday, March 16, 13

Page 17: Dynamic Code Patterns: Extending Your Applications with Plugins

Enabling

Explicit Implicit

DjangoPyramid

SQLAlchemyBlogofileMercurial

TracSphinx

virtualenvwrappercliff

9Saturday, March 16, 13

Page 18: Dynamic Code Patterns: Extending Your Applications with Plugins

Importing

Custom pkg_resources

DjangoPyramidSphinx

DiamondNova Nose

SQLAlchemyBlogofile

TracNose

SQLAlchemyBlogofile

cliffvirtualenvwrapper

10Saturday, March 16, 13

Page 19: Dynamic Code Patterns: Extending Your Applications with Plugins

Integration

Fine Coarse

Prompt

Inspect

Nosevirtualenvwrapper

SphinxTrac

cliffDiamond

MercurialBlogofilePyramidDjango

11Saturday, March 16, 13

Page 20: Dynamic Code Patterns: Extending Your Applications with Plugins

Integration

Fine Coarse

Prompt

Inspect

Nosevirtualenvwrapper

SphinxTrac

cliffDiamond

MercurialBlogofilePyramidDjango

12Saturday, March 16, 13

Page 21: Dynamic Code Patterns: Extending Your Applications with Plugins

API Enforcement

Convention Base Class / Interface

BlogofileMercurialDjangoSphinx

Pyramidvirtualenvwrapper

Nose (optional)Trac (interface)

Diamondcliff (abc)

13Saturday, March 16, 13

Page 22: Dynamic Code Patterns: Extending Your Applications with Plugins

Invocation

Driver Dispatcher Iterator

SQLAlchemyNova

MercurialDjangoPyramid

cliff

NoseDiamond

virtualenvwrapper

14Saturday, March 16, 13

Page 23: Dynamic Code Patterns: Extending Your Applications with Plugins

Discovery / Importing

• Entry Points

• Distribute and pkg_resources

• Be Consistent

15Saturday, March 16, 13

Page 24: Dynamic Code Patterns: Extending Your Applications with Plugins

Enabling

• Explicit disabling

• Automatic disabling

16Saturday, March 16, 13

Page 25: Dynamic Code Patterns: Extending Your Applications with Plugins

Integration

• Fine

• Inspect

• Application Owns Relationship

17Saturday, March 16, 13

Page 26: Dynamic Code Patterns: Extending Your Applications with Plugins

API Enforcement

• Abstract Base Classes

• Duck Typing

18Saturday, March 16, 13

Page 27: Dynamic Code Patterns: Extending Your Applications with Plugins

Invocation

• Storage – Driver

• Notifications – Dispatcher

• Pollsters – Iterator

19Saturday, March 16, 13

Page 28: Dynamic Code Patterns: Extending Your Applications with Plugins

stevedore

• Implements Patterns

• Wraps pkg_resources

20Saturday, March 16, 13

Page 29: Dynamic Code Patterns: Extending Your Applications with Plugins

NamedExtensionManager

• Multiple Plugins

• Only Loads Named Plugins

• map()

21Saturday, March 16, 13

Page 30: Dynamic Code Patterns: Extending Your Applications with Plugins

EnabledExtensionManager

• Multiple Plugins

• Checks Each with Function on Load

• map()

22Saturday, March 16, 13

Page 31: Dynamic Code Patterns: Extending Your Applications with Plugins

DispatchExtensionManager

• Multiple Plugins

• Invokes Subset on map()

23Saturday, March 16, 13

Page 32: Dynamic Code Patterns: Extending Your Applications with Plugins

DriverManager

• Single Plugin

• Direct Access

24Saturday, March 16, 13

Page 33: Dynamic Code Patterns: Extending Your Applications with Plugins

Dynamic Code Patterns:Extending Your

Applications with PluginsDoug Hellmann – @doughellmann – PyCon 2013

http://packages.python.org/distribute/pkg_resources.html

https://github.com/dreamhost/stevedore

https://launchpad.net/ceilometer

http://doughellmann.com

25Saturday, March 16, 13


Recommended