SlideShare une entreprise Scribd logo
1  sur  71
Télécharger pour lire hors ligne
Fighting API Compatibility
On Fluentd Using "Black Magic"
Jul 2 2016 in YAPC::Asia Hachioji
#yapc8oji
Satoshi "Moris" Tagomori (@tagomoris)
Satoshi "Moris" Tagomori
(@tagomoris)
Fluentd, MessagePack-Ruby, Norikra, ...
Treasure Data, Inc.
http://docs.fluentd.org/articles/logo
Fluentd v0.14 Release
Fluentd v0.14 API Update
• Everything changed :)
• Plugin namespace
• before: Fluent::* (Top level classes even for plugins!)
• after: Fluent::Plugin::*
• Plugin base class for common methods
• Inconsistent Output plugin hierarchy
• Plugin must call `super` in common methods
http://www.slideshare.net/tagomoris/fluentd-v014-plugin-api-details
Classes hierarchy (v0.12)
Fluent::Input F::Filter
F::Output
BufferedOutput
Object
Buffered
Time
Sliced
Multi
Output F::Buffer
F::Parser
F::Formatter
3rd party plugins
Classes hierarchy (v0.14)
F::P::Input F::P::Filter F::P::Output
Fluent::Plugin::Base
F::P::Buffer
F::P::Parser
F::P::Formatter
F::P::Storage
both of
buffered/non-buffered
F::P::
BareOutput
(not for 3rd party
plugins)
F::P::
MultiOutput
copy
roundrobin
diff v0.12 v0.14
F::P::Output
Fluent::Plugin::Base
both of
buffered/non-buffered
F::P::
BareOutput
(not for 3rd party
plugins)
F::P::
MultiOutput
copy
roundrobin
F::Output
BufferedOutput
Object
Buffered
Time
Sliced
Multi
Output
Super classes by

how to buffer data
All output plugins

are just "Output"
Basic Weapons:
Class and Mixin in Ruby
Class and Subclass in Ruby
class A
#bar
class B
#bar
super
B.new.bar
class A
#bar
class B
#bar
super
B.new.bar
module M
#bar
Introducing Methods by Mixin
class A
#bar
class B
#bar
super
B.new.bar
module M
#bar
Singleton Class of Ruby
#bar
B.new.singleton_class
class A
#bar
class B
#bar
super
b=B.new
b.singleton_class.include M2
b.bar
module M
#bar
Adding Methods on An Instance (1)
B.new.singleton_class
#bar
M2
#bar
class A
#bar
class B
#bar
super
b=B.new
b.extend M2
b.bar
module M
#bar
Adding Methods on An Instance (2)
B.new.singleton_class
#bar
M2
#bar
Back to Fluentd code :)
diff v0.12 v0.14
F::P::Output
Fluent::Plugin::Base
both of
buffered/non-buffered
F::P::
BareOutput
(not for 3rd party
plugins)
F::P::
MultiOutput
copy
roundrobin
F::Output
BufferedOutput
Object
Buffered
Time
Sliced
Multi
Output
Super classes by

how to buffer data
All output plugins

are just "Output"
Fluentd v0.12 Fluent::Output
class Fluent::Output
#emit(tag, es, chain)
MyOutput
Engine calls plugin.emit(tag, es, chain)
@buffer
Fluentd v0.12 Fluent::BufferedOutput (1)
class Fluent::Outputclass BufferedOutput
#emit(tag, es, chain, key)
MyOutput
#emit(tag, es, chain)
super(tag, es, chain, any_key)
Engine calls plugin.emit(tag, es, chain)
@buffer
#emit(key, data, chain)
#format(tag,time,record)
#format_stream(tag,es)
Fluentd v0.12 Fluent::BufferedOutput (2)
class Fluent::Outputclass BufferedOutput
#emit(tag, es, chain, key)
MyOutput
#emit(tag, es, chain)
super(tag, es, chain, any_key)
Engine calls plugin.emit(tag, es, chain)
@buffer
#emit(key, data, chain)
#format_stream(tag,es)
#format_stream(tag,es)
#format(tag,time,record)
Fluentd v0.12 Fluent::TimeSlicedOutput
class Fluent::Outputclass BufferedOutput
#emit(tag, es, chain, key)
MyOutput
#emit(tag, es, chain)
Engine calls plugin.emit(tag, es, chain)
@buffer
#emit(key, data, chain)
#emit(tag, es, chain) class TimeSlicedOutput
#format(tag,time,record)
Fluentd v0.12 Fluent::ObjectBufferedOutput
class Fluent::Outputclass BufferedOutput
#emit(tag, es, chain, key)
MyOutput
#emit(tag, es, chain)
Engine calls plugin.emit(tag, es, chain)
@buffer
#emit(key, data, chain)
#emit(tag, es, chain) class ObjectBufferedOutput
Fluentd v0.12 Fluent::BufferedOutput
class Fluent::Outputclass BufferedOutputMyOutput
@buffer calls #write in OutputThread
@buffer
chunk
#write(chunk)
OutputThread
#pop
Fluentd v0.12 Fluent::TimeSlicedOutput
class Fluent::Outputclass BufferedOutput
@buffer
MyOutput
class TimeSlicedOutput
OutputThread
#write(chunk)
@buffer calls #write in OutputThread
#write calls chunk.key
chunk
#pop
Fluentd v0.12 Fluent::ObjectBufferedOutput
class Fluent::Outputclass BufferedOutput
@buffer
MyOutput
class ObjectBufferedOutput
OutputThread
#write(chunk)
#write(chunk)
#write_object(chunk_key, chunk)
@buffer calls #write in OutputThread
chunk
#pop
Fluentd v0.12 API Problems
• Entry point method is implemented by Plugin subclasses
• Fluentd core cannot add any processes
• counting input events
• hook arguments/return values to update API
• Fluentd core didn't show fixed API
• Plugins have different call stacks
• It's not clear what should be implemented for authors
• It's not clear what interfaces are supported for
arguments/return values
How can we solve this problem?
Fluent::Plugin::Output (v0.14)
Fluentd v0.14 Fluent::Plugin::Output
class Outputclass MyOutput
#process(tag, es)
Engine calls plugin.emit_events(tag, es)
@buffer
#write
#emit_events(tag, es)
#format(tag, time, record)
#write(chunk)
#try_write(chunk)
#emit_sync(tag, es)
#emit_buffered(tag, es)
Fluentd v0.14 Fluent::Plugin::Output
class Outputclass MyOutput
Output calls plugin.write (or try_write)
@buffer
chunk
#write(chunk)
#try_write(chunk)
flush thread
#process(tag, es)
#format(tag, time, record)
Fluentd v0.14 Design Policy
• Separate entry points from implementations
• Methods in superclass control everything
• Do NOT override these methods!
• Methods in subclass do things only for themselves
• not for data flow, control flow nor others
• Plugins have simple/straightforward call stack
• Easy to understand/maintain
❤
How about existing
v0.12 plugins?
Requirement:
(Almost)
All Existing Plugins SHOULD

Work Well
WITHOUT ANY MODIFICATION
• Fluent::Compat namespace for compatibility layer
v0.14 Plugins & Compat Layer
F::P::Output
F::P::Base
v0.14 Plugins
Fluent::
Compat::
Output
F::C::
Buffered
Output
F::C::
TimeSliced
Output
F::C::
ObjectBuffered
Output
Fluent::Output
F::
Buffered
Output
F::
TimeSliced
Output
F::
ObjectBuffered
Output
v0.12 Plugins
Double Decker Compat Layer?
• Existing plugins inherits Fluent::Output or others
• No more codes in Fluent top level :-(
• Separate code into Fluent::Compat
• and import it into Fluent top level
Fluentd v0.14 Fluent::Plugin::Output
class Outputclass MyOutput
#process(tag, es)
Engine calls plugin.emit_events(tag, es)
@buffer
#write
#emit_events(tag, es)
#format(tag, time, record)
#write(chunk)
#try_write(chunk)
#emit_sync(tag, es)
#emit_buffered(tag, es)
Fluentd v0.12 Fluent::BufferedOutput (2)
class Fluent::Outputclass BufferedOutput
#emit(tag, es, chain, key)
MyOutput
#emit(tag, es, chain)
super(tag, es, chain, any_key)
Engine calls plugin.emit(tag, es, chain)
@buffer
#emit(key, data, chain)
#format_stream(tag,es)
#format_stream(tag,es)
#format(tag,time,record)
Fluent::Plugin::Outputclass MyOutput
@buffer
#write
#emit_events(tag, es)
v0.12 Plugins via Compat Layer: Best case (virtual)
Compat::BufferedOutput
#emit_buffered(tag, es)
#format(tag, time, record)
#format_stream(tag,es) #handle_stream_*
#handle_stream_simple
#emit(tag, es, chain, key) #emit(tag, es, chain, key)
#format_stream(tag,es)
#write(chunk)
flush thread
Fluent::Plugin::Outputclass MyOutput
@buffer
#write
#emit_events(tag, es)
v0.12 Plugins via Compat Layer: Best case (real)
Compat::BufferedOutput
#emit_buffered(tag, es)
#format(tag, time, record)
#format_stream(tag,es) #handle_stream_*
#handle_stream_simple
#emit(tag, es, chain, key) #emit(tag, es, chain, key)
#format_stream(tag,es)
#write(chunk)
flush thread
Fluent::Plugin::Outputclass MyOutput
@buffer
#write
#emit_events(tag, es)
When plugin overrides #format_stream
Compat::BufferedOutput
#emit_buffered(tag, es)
#format(tag, time, record)
#format_stream(tag,es) #handle_stream_*
#handle_stream_simple
#emit(tag, es, chain, key) #emit(tag, es, chain, key)
#format_stream(tag,es)
#write(chunk)
flush thread
Fluent::Plugin::Outputclass MyOutput
@buffer
#write
#emit_events(tag, es)
When plugin overrides #format_stream
Compat::BufferedOutput
#emit_buffered(tag, es)
#format(tag, time, record)
#format_stream(tag,es) #handle_stream_*
#handle_stream_simple
#emit(tag, es, chain, key) #emit(tag, es, chain, key)
#format_stream(tag,es)
#write(chunk)
flush thread
default implementation
for calling "super"
Fluent::Plugin::Outputclass MyOutput
@buffer
#write
#emit_events(tag, es)
When plugin overrides #emit
Compat::BufferedOutput
#emit_buffered(tag, es)
#format(tag, time, record)
#format_stream(tag,es) #handle_stream_*
#handle_stream_simple
#emit(tag, es, chain) #emit(tag, es, chain, key)
#format_stream(tag,es)
#write(chunk)
flush thread
Fluent::Plugin::Outputclass MyOutput
@buffer
#write
#emit_events(tag, es)
Compat::BufferedOutput
#emit_buffered(tag, es)
#format(tag, time, record)
#format_stream(tag,es) #handle_stream_*
#handle_stream_simple
#emit(tag, es, chain) #emit(tag, es, chain, key)
#format_stream(tag,es)
#write(chunk)
flush thread
When plugin overrides #emit
Fluent::Plugin::Outputclass MyOutput
@buffer
#write
#emit_events(tag, es)
Compat::BufferedOutput
#emit_buffered(tag, es)
#format(tag, time, record)
#format_stream(tag,es) #handle_stream_*
#handle_stream_simple
#emit(tag, es, chain) #emit(tag, es, chain, key)
#format_stream(tag,es)
#write(chunk)
flush thread
This call doesn't happen, in fact
#emit doesn't return values!
When plugin overrides #emit
Fluent::Plugin::Outputclass MyOutput
@buffer
#write
#emit_events(tag, es)
When plugin overrides #emit
Compat::BufferedOutput
#emit_buffered(tag, es)
#format(tag, time, record)
#format_stream(tag,es) #handle_stream_*
#handle_stream_simple
#emit(tag, es, chain) #emit(tag, es, chain, key)
#format_stream(tag,es)
#write(chunk)
flush thread
#emit calls @buffer.emit
→ NoMethodError !
Fluent::Plugin::Outputclass MyOutput
@buffer
#write
#emit_events(tag, es)
When plugin overrides #emit
Compat::BufferedOutput
#emit_buffered(tag, es)
#format(tag, time, record)
#format_stream(tag,es) #handle_stream_*
#handle_stream_simple
#emit(tag, es, chain) #emit(tag, es, chain, key)
#format_stream(tag,es)
#write(chunk)
flush thread
Fluent::Plugin::Outputclass MyOutput
@buffer
#write
#emit_events(tag, es)
When plugin overrides #emit
Compat::BufferedOutput
#emit_buffered(tag, es)
#format(tag, time, record)
#format_stream(tag,es) #handle_stream_*
#handle_stream_simple
#emit(tag, es, chain) #emit(tag, es, chain, key)
#format_stream(tag,es)
#write(chunk)
flush thread
#emit
1. #emit calls @buffer.emit with data to be written in buffer
0. plugin calls @buffer.extend to add #emit
2. @buffer.emit stores arguments into plugin's attribute
3. get stored data
4. call @buffer.write with data
Fluent::Plugin::Outputclass MyOutput
@buffer
#write
#emit_events(tag, es)
When plugin overrides #emit
Compat::BufferedOutput
#emit_buffered(tag, es)
#format(tag, time, record)
#format_stream(tag,es) #handle_stream_*
#handle_stream_simple
#emit(tag, es, chain) #emit(tag, es, chain, key)
#format_stream(tag,es)
#write(chunk)
flush thread
Fluent::Plugin::Outputclass MyOutput
@buffer
#write
#emit_events(tag, es)
Thinking about "chunk" instance ...
Compat::BufferedOutput
#emit_buffered(tag, es)
#format(tag, time, record)
#format_stream(tag,es) #handle_stream_*
#handle_stream_simple
#emit(tag, es, chain) #emit(tag, es, chain, key)
#format_stream(tag,es)
#write(chunk)
flush thread
#write may call "chunk.key",
but v0.14 chunk doesn't have #key !
Fluent::Plugin::Outputclass MyOutput
@buffer
#write
Compat::BufferedOutput
#write(chunk)
flush thread
"chunk" has #metadata, and values
of #key can be created via #metadata
Let's "chunk.extend" !
Where to do so?
?
Thinking about "chunk" instance ...
Fluent::Plugin::OutputMyOutput
@buffer
#write
C::BufferedOutput
#write(chunk) flush thread
Thinking about "chunk" instance ...
#write(chunk)
BufferedChunkMixin
plugin.extend BufferedChunkMixin
in #configure
Similar hacks for
TimeSlicedOutput and
ObjectBufferedOutput ...
Controlling Plugin Lifecycle
Plugin Lifecycle Updated
Methods(v0.12)
• #configure
• #start
• #before_shutdown
• #shutdown
v0.12 Plugins often
doesn't call "super"!
Methods(v0.14)
• #configure
• #start
• #stop
• #before_shutdown
• #shutdown
• #after_shutdown
• #close
• #terminate
In v0.14, these methods MUST call "super"
• #configured?
• #started?
• #stopped?
• #before_shutdown?
• #shutdown?
• #after_shutdown?
• #closed?
• #terminated?
For Example: shutdown compat plugins
Fluent::Plugin::Base
#shutdown
F::P::Output
super
#shutdown?
#shutdown
F::C::Output
#shutdown
MyOutput
#shutdown
It doesn't call "super"! We want to call this...
What We Want To Do:
Fluent::Plugin::Base
#shutdown
F::P::Output
super
#shutdown?
#shutdown
F::C::Output
#shutdown
MyOutput
#shutdown
1. call #shutdown anyway
0. Fluentd core calls #shutdown
2. call #shutdown? to check "super" is called or not
3. call #shutdown of superclass forcedly!
What We Want To Do:
Fluent::Plugin::Base
#shutdown
F::P::Output
super
#shutdown?
#shutdown
F::C::Output
#shutdown
MyOutput
#shutdown
How to make this point?
More Weapon!
Module#prepend
class A
#bar
class B
#bar
super
B.new.bar
Wrapping Methods on a Class (1)
B.new.singleton_class
#bar
class A
#bar
class B
#bar
super
B.new.bar
module M
Wrapping Methods on a Class (2)
B.new.singleton_class
#bar
#bar
Using extend is powerful,
but it should be done for all instances
How about wrapping methods for
all instances of the class?
class A
#bar
class B
#bar
super
module M;def bar;super;end;end
B.prepend M
B.new.bar
module M
Wrapping Methods on a Class (3): Module#prepend
B.new.singleton_class
#bar
#bar
module M wraps B, and
M#bar is called at first
class A
#bar
class B
#bar
super
b=B.new
b.singleton_class.module_eval{define_method(:bar){"1"}}
b.bar
Another Study: How To Wrap Singleton Method?
B.new.singleton_class
#bar
class A
#bar
class B
#bar
super
module M
Another Study: How To Wrap Singleton Method?
B.new.singleton_class
#bar
Singleton class is a class,
so it can be prepended :)
b=B.new
b.singleton_class.module_eval{define_method(:bar){"1"}}
b.singleton_class.prepend M
b.bar
#bar
It's actually done in Test Driver implementation...
What We Want To Do:
Fluent::Plugin::Base
#shutdown
F::P::Output
super
#shutdown?
#shutdown
F::C::Output
#shutdown
MyOutput
#shutdown
THIS ONE !!!
What We Got :-)
Fluent::Plugin::Base
#shutdown
F::P::Output
super
#shutdown?
#shutdown
F::C::Output
#shutdown
MyOutput
#shutdown
1. call #shutdown anyway
0. prepend CallSuperMixin at first
2. call #shutdown? to check "super" is called or not
3. if not, get method of superclass, bind self with it, then call it
Thank you @unak -san!
IS BUILT ON A TOP OF
BUNCH OF BLACK MAGICS :P
Do Whatever You Can
For Users!
It Makes Everyone Happier
... Except for Maintainers :(

Contenu connexe

Tendances

Tendances (20)

Fluentd v1 and Roadmap
Fluentd v1 and RoadmapFluentd v1 and Roadmap
Fluentd v1 and Roadmap
 
Fluentd Unified Logging Layer At Fossasia
Fluentd Unified Logging Layer At FossasiaFluentd Unified Logging Layer At Fossasia
Fluentd Unified Logging Layer At Fossasia
 
System Programming and Administration
System Programming and AdministrationSystem Programming and Administration
System Programming and Administration
 
Composer the right way - SunshinePHP
Composer the right way - SunshinePHPComposer the right way - SunshinePHP
Composer the right way - SunshinePHP
 
Php internal architecture
Php internal architecturePhp internal architecture
Php internal architecture
 
このPHP拡張がすごい!2017
このPHP拡張がすごい!2017このPHP拡張がすごい!2017
このPHP拡張がすごい!2017
 
OSCON2014 : Quick Introduction to System Tools Programming with Go
OSCON2014 : Quick Introduction to System Tools Programming with GoOSCON2014 : Quick Introduction to System Tools Programming with Go
OSCON2014 : Quick Introduction to System Tools Programming with Go
 
HipHop Virtual Machine
HipHop Virtual MachineHipHop Virtual Machine
HipHop Virtual Machine
 
Taming the resource tiger
Taming the resource tigerTaming the resource tiger
Taming the resource tiger
 
Learning Python from Data
Learning Python from DataLearning Python from Data
Learning Python from Data
 
Python at Facebook
Python at FacebookPython at Facebook
Python at Facebook
 
Introduction to Programming in Go
Introduction to Programming in GoIntroduction to Programming in Go
Introduction to Programming in Go
 
Docker and Fluentd
Docker and FluentdDocker and Fluentd
Docker and Fluentd
 
LuaJIT
LuaJITLuaJIT
LuaJIT
 
PyCon Taiwan 2013 Tutorial
PyCon Taiwan 2013 TutorialPyCon Taiwan 2013 Tutorial
PyCon Taiwan 2013 Tutorial
 
Dive into Fluentd plugin v0.12
Dive into Fluentd plugin v0.12Dive into Fluentd plugin v0.12
Dive into Fluentd plugin v0.12
 
Lua and its Ecosystem
Lua and its EcosystemLua and its Ecosystem
Lua and its Ecosystem
 
Php extensions
Php extensionsPhp extensions
Php extensions
 
Go for SysAdmins - LISA 2015
Go for SysAdmins - LISA 2015Go for SysAdmins - LISA 2015
Go for SysAdmins - LISA 2015
 
Apache Thrift
Apache ThriftApache Thrift
Apache Thrift
 

En vedette

AWSにおけるバッチ処理の ベストプラクティス - Developers.IO Meetup 05
AWSにおけるバッチ処理の ベストプラクティス - Developers.IO Meetup 05AWSにおけるバッチ処理の ベストプラクティス - Developers.IO Meetup 05
AWSにおけるバッチ処理の ベストプラクティス - Developers.IO Meetup 05
都元ダイスケ Miyamoto
 

En vedette (12)

How To Write Middleware In Ruby
How To Write Middleware In RubyHow To Write Middleware In Ruby
How To Write Middleware In Ruby
 
Open Source Software, Distributed Systems, Database as a Cloud Service
Open Source Software, Distributed Systems, Database as a Cloud ServiceOpen Source Software, Distributed Systems, Database as a Cloud Service
Open Source Software, Distributed Systems, Database as a Cloud Service
 
Fluentd Overview, Now and Then
Fluentd Overview, Now and ThenFluentd Overview, Now and Then
Fluentd Overview, Now and Then
 
20160730 fluentd meetup in matsue slide
20160730 fluentd meetup in matsue slide20160730 fluentd meetup in matsue slide
20160730 fluentd meetup in matsue slide
 
How to Make Norikra Perfect
How to Make Norikra PerfectHow to Make Norikra Perfect
How to Make Norikra Perfect
 
The Patterns of Distributed Logging and Containers
The Patterns of Distributed Logging and ContainersThe Patterns of Distributed Logging and Containers
The Patterns of Distributed Logging and Containers
 
AWSにおけるバッチ処理の ベストプラクティス - Developers.IO Meetup 05
AWSにおけるバッチ処理の ベストプラクティス - Developers.IO Meetup 05AWSにおけるバッチ処理の ベストプラクティス - Developers.IO Meetup 05
AWSにおけるバッチ処理の ベストプラクティス - Developers.IO Meetup 05
 
To Have Own Data Analytics Platform, Or NOT To
To Have Own Data Analytics Platform, Or NOT ToTo Have Own Data Analytics Platform, Or NOT To
To Have Own Data Analytics Platform, Or NOT To
 
Perfect Norikra 2nd Season
Perfect Norikra 2nd SeasonPerfect Norikra 2nd Season
Perfect Norikra 2nd Season
 
Ruby and Distributed Storage Systems
Ruby and Distributed Storage SystemsRuby and Distributed Storage Systems
Ruby and Distributed Storage Systems
 
Fluentd v0.14 Plugin API Details
Fluentd v0.14 Plugin API DetailsFluentd v0.14 Plugin API Details
Fluentd v0.14 Plugin API Details
 
Distributed Logging Architecture in Container Era
Distributed Logging Architecture in Container EraDistributed Logging Architecture in Container Era
Distributed Logging Architecture in Container Era
 

Similaire à Fighting API Compatibility On Fluentd Using "Black Magic"

The Kotlin Programming Language
The Kotlin Programming LanguageThe Kotlin Programming Language
The Kotlin Programming Language
intelliyole
 

Similaire à Fighting API Compatibility On Fluentd Using "Black Magic" (20)

Fluentd - road to v1 -
Fluentd - road to v1 -Fluentd - road to v1 -
Fluentd - road to v1 -
 
The Swift Compiler and Standard Library
The Swift Compiler and Standard LibraryThe Swift Compiler and Standard Library
The Swift Compiler and Standard Library
 
7 Tips on Getting Your Theme Approved the First Time
7 Tips on Getting Your Theme Approved the First Time7 Tips on Getting Your Theme Approved the First Time
7 Tips on Getting Your Theme Approved the First Time
 
Dart
DartDart
Dart
 
The why and how of moving to php 5.4
The why and how of moving to php 5.4The why and how of moving to php 5.4
The why and how of moving to php 5.4
 
Exploring Async PHP (SF Live Berlin 2019)
Exploring Async PHP (SF Live Berlin 2019)Exploring Async PHP (SF Live Berlin 2019)
Exploring Async PHP (SF Live Berlin 2019)
 
Specialized Compiler for Hash Cracking
Specialized Compiler for Hash CrackingSpecialized Compiler for Hash Cracking
Specialized Compiler for Hash Cracking
 
Exakat for PHP : smart code reviewing engine
Exakat for PHP : smart code reviewing engineExakat for PHP : smart code reviewing engine
Exakat for PHP : smart code reviewing engine
 
A Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to GoA Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to Go
 
Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)
Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)
Kicking off with Zend Expressive and Doctrine ORM (PHPNW2016)
 
Python_UNIT-I.pptx
Python_UNIT-I.pptxPython_UNIT-I.pptx
Python_UNIT-I.pptx
 
The Kotlin Programming Language
The Kotlin Programming LanguageThe Kotlin Programming Language
The Kotlin Programming Language
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy Code
 
PHP 5.3
PHP 5.3PHP 5.3
PHP 5.3
 
Php training100%placement-in-mumbai
Php training100%placement-in-mumbaiPhp training100%placement-in-mumbai
Php training100%placement-in-mumbai
 
A Life of breakpoint
A Life of breakpointA Life of breakpoint
A Life of breakpoint
 
C Sharp Course 101.5
C Sharp Course 101.5C Sharp Course 101.5
C Sharp Course 101.5
 
Adventurous Merb
Adventurous MerbAdventurous Merb
Adventurous Merb
 
Kicking off with Zend Expressive and Doctrine ORM (ZendCon 2016)
Kicking off with Zend Expressive and Doctrine ORM (ZendCon 2016)Kicking off with Zend Expressive and Doctrine ORM (ZendCon 2016)
Kicking off with Zend Expressive and Doctrine ORM (ZendCon 2016)
 
Coding in GO - GDG SL - NSBM
Coding in GO - GDG SL - NSBMCoding in GO - GDG SL - NSBM
Coding in GO - GDG SL - NSBM
 

Plus de SATOSHI TAGOMORI

Plus de SATOSHI TAGOMORI (19)

Ractor's speed is not light-speed
Ractor's speed is not light-speedRactor's speed is not light-speed
Ractor's speed is not light-speed
 
Good Things and Hard Things of SaaS Development/Operations
Good Things and Hard Things of SaaS Development/OperationsGood Things and Hard Things of SaaS Development/Operations
Good Things and Hard Things of SaaS Development/Operations
 
Maccro Strikes Back
Maccro Strikes BackMaccro Strikes Back
Maccro Strikes Back
 
Invitation to the dark side of Ruby
Invitation to the dark side of RubyInvitation to the dark side of Ruby
Invitation to the dark side of Ruby
 
Hijacking Ruby Syntax in Ruby (RubyConf 2018)
Hijacking Ruby Syntax in Ruby (RubyConf 2018)Hijacking Ruby Syntax in Ruby (RubyConf 2018)
Hijacking Ruby Syntax in Ruby (RubyConf 2018)
 
Make Your Ruby Script Confusing
Make Your Ruby Script ConfusingMake Your Ruby Script Confusing
Make Your Ruby Script Confusing
 
Hijacking Ruby Syntax in Ruby
Hijacking Ruby Syntax in RubyHijacking Ruby Syntax in Ruby
Hijacking Ruby Syntax in Ruby
 
Lock, Concurrency and Throughput of Exclusive Operations
Lock, Concurrency and Throughput of Exclusive OperationsLock, Concurrency and Throughput of Exclusive Operations
Lock, Concurrency and Throughput of Exclusive Operations
 
Data Processing and Ruby in the World
Data Processing and Ruby in the WorldData Processing and Ruby in the World
Data Processing and Ruby in the World
 
Planet-scale Data Ingestion Pipeline: Bigdam
Planet-scale Data Ingestion Pipeline: BigdamPlanet-scale Data Ingestion Pipeline: Bigdam
Planet-scale Data Ingestion Pipeline: Bigdam
 
Technologies, Data Analytics Service and Enterprise Business
Technologies, Data Analytics Service and Enterprise BusinessTechnologies, Data Analytics Service and Enterprise Business
Technologies, Data Analytics Service and Enterprise Business
 
Fluentd 101
Fluentd 101Fluentd 101
Fluentd 101
 
Overview of data analytics service: Treasure Data Service
Overview of data analytics service: Treasure Data ServiceOverview of data analytics service: Treasure Data Service
Overview of data analytics service: Treasure Data Service
 
Hive dirty/beautiful hacks in TD
Hive dirty/beautiful hacks in TDHive dirty/beautiful hacks in TD
Hive dirty/beautiful hacks in TD
 
Data Analytics Service Company and Its Ruby Usage
Data Analytics Service Company and Its Ruby UsageData Analytics Service Company and Its Ruby Usage
Data Analytics Service Company and Its Ruby Usage
 
Tale of ISUCON and Its Bench Tools
Tale of ISUCON and Its Bench ToolsTale of ISUCON and Its Bench Tools
Tale of ISUCON and Its Bench Tools
 
Data Analytics Service Company and Its Ruby Usage
Data Analytics Service Company and Its Ruby UsageData Analytics Service Company and Its Ruby Usage
Data Analytics Service Company and Its Ruby Usage
 
Data-Driven Development Era and Its Technologies
Data-Driven Development Era and Its TechnologiesData-Driven Development Era and Its Technologies
Data-Driven Development Era and Its Technologies
 
Engineer as a Leading Role
Engineer as a Leading RoleEngineer as a Leading Role
Engineer as a Leading Role
 

Dernier

Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
masabamasaba
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
VictoriaMetrics
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
masabamasaba
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
masabamasaba
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
masabamasaba
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
shinachiaurasa2
 

Dernier (20)

Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
tonesoftg
tonesoftgtonesoftg
tonesoftg
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 

Fighting API Compatibility On Fluentd Using "Black Magic"