2019/11/3 YAPC::Nagoya::Tiny 2019
hitode909

hitode909
2017
x4x1
PerlTypeScript
2018 PerlISUCON
2019 Node.JS退
VJ
Gyazo
(1)

VSCodePerlformatOnType
"editor.formatOnType": true perltidy-more
Gyazo



GigaViewer
WEB
2017179

https://kuragebunch.com/
https://comicborder.com/
https://comic-zenon.com/episode/10834108156688950516
(3)

使
API使

Gyazo

Host
Perl5Perl
(MySQL)
1
media_id(id)
Redis
media_id
1
(5)

vs
Core=, Media =
11
1
Host
Media
Mediamedia.id使
(7)
()


11010

12
config production => {
'root-uri.jump_plus' => 'https://shonenjumpplus.com',
};
config staging => {
'root-uri.jump_plus' => 'https://giga-jump-plus.example.com',
};
config local => {
'root-uri.jump_plus' => 'http://giga-jump-plus.localhost:3000',
};

2
調96
config production => {
'root-uri.jump_plus' => 'https://shonenjumpplus.com',
'root-uri.tonarino_yj' => 'https://tonarinoyj.jp/',
};
config staging => {
'root-uri.jump_plus' => 'https://giga-jump-plus.example.com',
'root-uri.tonarino_yj' => 'https://giga-tonarino-yj.example.com',
};
config local => {
'root-uri.jump_plus' => 'http://giga-jump-plus.localhost:3000',
'root-uri.tonarino_yj' => 'http://giga-tonarino-yj.localhost:3000',
};

使
productionURL media.name 使
config staging => {
'root-uri.pattern' => 'https://giga-%s.example.com',
};
config local => {
'root-uri.pattern' => 'http://giga-%s.localhost:3000',
};
(8)

OGPTwittermeta
sub page_title { "$page_name - $site_name" }
OGPMetaTwitter
YAML
YAMLJSON SchemaVSCode

使
Giga::Batch::Media::Comicdays::ContentSalesReport
Controller
Giga::Web::Core::Viewer
Giga::Web::Media::Comicdays::Top
(10)
()

(Media)(Feature)
Core
Feature
Giga::Feature::
3020%Feature/
Giga::Repository::Product Giga::Feature::Payment::Product::Repository
Gyazo

has_feature
5
使調Feature
(feature_names)Media
Gyazo
$media->has_feature()
if ($media->has_feature('UserAccount') { }
if ($media->has_feature('Shop') { }
has_feature
@startuml
class Media {
id
name
feature_names
+ has_feature(feature_name)
}
@enduml

: has_feature
media->has_feature使View

: has_feature
controller
sub user_account_detail {
return $c->error(400) unless $c->media->has_feature('UserAccount');
...;
}

has_feature
GET '/user_account/:user_account_id' => 'Giga::Admin::UserAccount#user_account_detail', { has_feature => ['UserAccount] };

: has_feature
Feature
package Giga::Feature::UserAccount::Service;
use Giga::HasFeature q(UserAccount);
sub get_signup_credential_data {
args my $class => 'ClassName',
my $media => 'Giga::Media',
my $secret_token => 'Str',
;
...
}
UserAccount featuremedia
12
3
# on_scope_end 使
use B::Hooks::EndOfScope;
#
use Module::Functions ();
# Class::Method::Modifiers::install_modifier 使has_feature
use Class::Method::Modifiers ();

便(Perl)
sub import {
my ($class, @feature_names) = @_;
my $pkg = caller;
on_scope_end {
my $all_functions = [ grep { /\A[a-z]/ } Module::Functions::get_public_functions($pkg) ];
Class::Method::Modifiers::install_modifier($pkg, 'before', $all_functions, sub {
my ($self, %args) = shift;
my @missing = grep { !$media->has_feature($_) } @feature_names;
Carp::confess "Feature " . join(', ', @missing) . " is not allowed for @{[ $media->name ]}" if @missing;
});
}

my $data = Giga::Feature::UserAccount::Service->get_signup_credential_data(media => $media, token => ...);
使CI
(13)

GigaViewerFeatureFeature Toggles
FeatureFeature Toggles
Permissioning Toggles
Feature Toggles
Feature Toggles
Release Toggles
Experiment Toggle
A/B
Ops Toggle
Permissioning Toggles
canary release

Giga::FeatureRelease Toggles使
media->wip_features
$media->enable_feature 1Feature
wip_features_namesfeature_names
便
Gyazo
@startuml
class Media {
id
name
feature_names
wip_feature_names
+ has_feature(feature_name)
+ enable_feature(feature_name)
}
@enduml

Mediahas_feature
Mediahas_feature使
(Easy)
使
ControllerModelSimple
(15)
()


Google DocsScrapbox

Gyazo

Gyazo
WikiXP
Gyazo Gyazo

Google Presentation使
Gyazo
Gyazo
Gyazo


Gyazo

node_modules3
Gyazo

2Google Jamboard
> Gyazo Gyazo
(18)


controller


(30)