読者です 読者をやめる 読者になる 読者になる

第10回 Apache Cordova勉強会 @ Sony City Osakiに参加してきました!

今日は別件でアポがあって東京出張に来ていたのですが、上手くスケジュールが重なって(というか重ねて) 第10回 Apache Cordova勉強会 に参加してきました。

アシアル株式会社の田中さんによる「Vue 2についての発表(仮)」にはじまり、(株)ジェイアイエヌの佐藤さんによる「WEBエンジニアの可能性を広げるJINS MEMEのアプリ開発」、最後にソニーネットワークコミュニケーションズ㈱ の緒方さんによる「Cordova を使って本気で商用ハイブリッドアプリケーション開発をやってみた」という発表をして、その後に懇親会という流れでイベントは進みました。

みなさん興味深いお話をして頂きとても楽しかったのですが、個人的に一番インパクトがあったのが緒方さんよる発表で、開発したアプリを見せて頂いたのでしたがUI/UX、アニメショーンの動きなどがとてもハイブリッドアプリで作ったとは思えない程の完成度でとても衝撃を受けました。

Cordova使ったハイブリッドアプリの開発者なら誰もが「ハイブリッドアプリだからネイティブアプリのような体験は作れない」と諦めてしまいがちですが、「ユーザーにはネイティブもハイブリッドも関係ない、ユーザーの期待値はネイティブ」、「ハイブリッドアプリのメリットはネイティブをそれぞれ作る以上の生産性、そこを失ってはいけない」とクオリティと生産性を両立させるための高い基準を設定し、それを達成するために行ったさまざま工夫やノウハウを今回の発表や懇親会でのコミュケーションを通して共有して頂きました。

スケジュール、技術的制約、高い達成基準などがあるなかでしっかりとそれを達成するために開発に向き合う姿勢はエンジニアとして尊敬するとともに、現在のモバイルアプリの環境であればネイティブにも遜色ないUXをCordovaでも作れるという可能性を見せて頂けたとても良い会になりました。

Cordovaを使ったハイブリッドアプリ開発、がんばろ!!

2017年3月1日をもって、琉球インタラクティブからPayke(ペイク)に転職しました

2017年2月28日を持って4年間働いていた琉球インタラクティブを卒業し、Paykeに転職しました。 沖縄のネット系ベンチャーから沖縄のアプリ系スタートアップへの転職という形になります。

前職について

初めてプログラマーとして職をついたのがこの会社だったのですが、ECサイト、公共施設の予約システム、WordPressを使ったサイト構築、エンジニア向けイベント情報サービスの機能開発や沖縄の求人サービスの開発など様々なWebサービス開発にメインのエンジニアとして入る事ができ技術力をとても鍛える事ができました。

また最後の1年半はバイトや外部パートナー含めて最大10名のエンジニアチームのマネジャーも経験させて頂きました。

ベンチャー特有の急激な環境の変化や無茶振り、抜擢人事などはいろんな意味で大変なことも多いですが、 たとえ問題が起きても誰か一人の責任にせずに、誰もが協力して問題解決に取り組む文化、 プロセスは担当者に任せて結果重視で評価することで、様々なプロセスを担当者レベルでどんどん改善出来る文化、 結果を出している人は報酬やランクアップを通して積極的に評価する文化などは 自分のこれからのキャリアを作る上での大事な下地になったともに、個人的にとても働きやすい会社でした。

最終出社日の記念写真 f:id:arakaji-yuu:20170309114130j:plain

自分は新たなチャレンジのために卒業しましたが、もし沖縄でもベンチャーの荒波に揉まれてジェットコースターのようなキャリアを歩みたいという方はぜひ琉球インタラクティブのリクルートを覗いてみて下さい^^*

なぜPaykeに転職したのか

自分のエンジニアとしてスキルやキャリアを高めるために新たな環境に身をおきたいと思い、半年程かけて転職活動を粛々として行っていまして、その間様々なベンチャー企業やスタートアップから声をかけていただきました。

どの会社も非常に優秀なエンジニアが揃っていたりとても魅力的なプロダクトが揃っていたのですが、Paykeを選んだ理由が一番課題や可能性が多くておもしろいと感じたからです。

Paykeのサービスはアプリでバーコードをスキャンすると、その商品情報が多言語で閲覧できるというインバウンド向けサービスなのですが、 メインのユーザーが訪日外国人であるためいつも自分が使うアプリとは違う視点で考えて開発しないといけないことや、 大量のスキャンデータや商品情報を扱うためのデータ分析基盤を作ること、 スキャンして表示する商品情報の数が数百~数千万、または億まで行ったときに出来ることや スキャン時得られる商品情報をよりユーザーに最適化した情報を出せるようにすることなど、 現時点で様々な課題と可能性があり、そこにエンジニアとして挑戦することに強い魅力を感じてJoinすることに決めました。

自分の技術力を高めてプロダクトに反映し、機会があればその経験をシェアしていきたいと思います。 今後ともよろしくお願いします。

オフィスの風景

f:id:arakaji-yuu:20170307193608j:plain

初出社日の満面の笑み

f:id:arakaji-yuu:20170301110039j:plain

受託開発は狩り、自社サービス開発は稲作

昨日ふと思っただけなんですが、受託開発は狩りっぽくて自社サービスは稲作っぽいなと。

受託開発がメインの場合は狩りをしている感覚で、自分の獲物がたくさんいる領域を探したり、大きな獲物を数多く確実に捕らえられるように牙を磨いている。大きな狩りに成功すればしばらくは安泰ですが、しっかり次の獲物を探しておかないといけないので、ずっと研ぎ澄ましている感じ。

自社サービスがメインの場合は稲作している感覚で、実りが出るまでは辛いんだけど実りが出るようになれば安定的に食料にありつけるようになる。ひとつの稲作に成功したらそれである程度食料は確保できるので、今度は違う種類の食材に挑戦したり、より大きく収穫できるように工夫していく。

なんでそんなことを思ったかというと、ただ偶然にYouTubeでレキシっていう人の「狩りから稲作へ」っていう曲を聞いたからなんですが。


狩りから稲作へ

あ、特に結論のようなものはないですよ?

チャットだけが仕事のメインコミュニケーションツールだと問題が出てくるのでプロジェクト管理ツールも使おう。

自分のいまの仕事環境だとメインのコミュニケーションツールにChatWorkを使っています。それ自体は良いことでプロジェクト毎にチャットグループを作ってそこでコミュニケーションを行うことでメールや口頭だけコミュニケーションを取るよりも素早く情報共有ができるし、あとで困ったときに検索することもできるのでとても便利です。

ただ業務上Webの受託開発がメインで、お仕事もおかげ様でたくさん頂けているので普通に10、20のプロジェクトのチャットグループが同時進行で動いています。 それだけのチャットが同時動いているとあまりにも情報過多で、仕事に集中する時間をとることも難しくなってきます。

チャットがメインのコミュニケーションの中で仕事する上で色々問題点が上がってきたのでまとめてました。

コミュニケーションがチャットグループにしか紐付いていない。

チャットだとチャットグループ一つにつきスレッドが一つです。 一つのプロジェクトで一つのチャットグループの場合、そのプロジェクトに関わる様々なタスクに関する議論を一つのスレッドでおこなうことになります。 これにより、特定のことで議論が活発になっているときにはそれが収まるまで他の話をしたい人は待っていたり、逆に割って入ることで議論が追いづらくなります。

タスク管理が貧弱

当たり前ですがチャットはチャットなので、タスク管理機能はついていてもおまけのようなものです。 チャットで仕事を依頼したあとも結局それを管理するためにはエクセルなり、タスク・プロジェクト管理ツールが必要なります。

未読消化するために時間がかかる

仕事上でのタスクの依頼や情報共有、細かいやり取りなどがすべてチャット上に集約されるとものすごい量の投稿数になります。 プロジェクト管理ツールなどでタスクに紐付いたコメントとしてやり取りする場合にはそのタスクに関わる人のみがコメントを読めば済みますが、チャットだとチャットグループに入っている人全員が読むことになります。 その投稿が重要かどうかも読むまでわからないので、結果自分には関係の少ないもの読まなくてはならず、そのために手を止めてしまいます。

一つの解決方法としてBackLogの併用

いま挙げた問題点を解消するために自分がメインで入るプロジェクトでは積極的にBackLogというプロジェクト管理ツールを使い始めました。

コミュニケーションが課題に紐付く

BackLogは各プロジェクトの中に課題というのを登録します。そしてその課題を誰かに依頼したり、議論があればその課題上にコメントすることでコミュニケーションを行います。そのため話が課題に紐付いていることがわかりやすいのでコミュニケーションがやりやすくなります。

タスク管理がしっかりできる

BackLogはプロジェクト管理ツールでベースとなる活動は課題を登録することです。その課題の担当がだれが、期限はいつか、優先度はどれくらいかなどが設定できるのでタスク管理をしっかりチームで行うことができます。まあプロジェクト管理ツールなんで当たり前ですが。

情報が整理されてノイズが減る

タスクの依頼はBackLogで課題を登録して担当者を割り振ることで行います。 課題に関する追加情報や議論があればBackLogの課題上でコメントし、伝えたい人にNotificationを送ることもできます。 プロジェクト全体に関わる情報でストックして見直したい情報、メンテナンスし続ける情報などはBackLogのWIKIにまとめておく事ができます。 それ以外の話や緊急な話のみChatでやり取りするので、情報が自然に整理されてノイズとなる情報がやっていきます。

終わりに

チャットだけだとどんどん未整理に膨らんでいく情報をプロジェクト管理ツールを使うことである程度整理して扱うことができ、結果的に自分の実作業に集中する時間が取りやすくなりました。 いまは自分がメインで入る仕事だけで使っているから上手くいっているだけで、これを全プロジェクトで行うとまた違う問題が出てきそうな気がしますが概ね正しいアプローチだとも思うので、徐々に普及活動もしていこうかなとも思っております。

JAWS Festa Kyusyu 2015 というイベントで発表してきました。

ブログを書くまでが勉強会ということで、少しおそくなりましたがブログを書きます。

題名の通り、JAWS Festa 2015 | 九州IT産業革命というイベントで発表してきました。

このイベントは「九州IT産業革命」というテーマのもとAWSを基盤とするさまざま事例や最新技術に触れると同時に、全国から集まるAWSユーザーと交流するのが目的のイベントとなっていて、 自分は「九州事例Trac」という枠でAWSの活用事例を発表してきました。

九州事例Tracクラウドネイティブが行なういまどきWebサービス開発」

発表内容は、自分がいま開発しているJobAntennaという沖縄の求人サイトをAWSを使って構築しているので、そこでAWSを前提したことで出来たことをピックアップして紹介しているような内容です^^

www.jobantenna.jp

九州事例座談会「九州のクラウド事情って?」

発表が終わって油断していたら、九州事例座談会「九州のクラウド事情って?」というセッションがあることを当日知り、大した準備も出来ないままセッションがスタートしました^^;

ちゃんと沖縄のクラウド事情が伝えらればよかったですが、心配です・・・

f:id:arakaji-yuu:20151108194231j:plain

懇親会

懇親会は100名程が参加する、超大規模な懇親会でした!!

こんな規模の懇親会に参加するのも始めてですし、スタート同時にLT大会が始まって懇親会時間の3/4はほぼLTを聞いている時間になったのも初めてでした^^;

さすがJAWSに参加している方々、みんなLTの内容も秀逸で聞いているだけでビールが進みましたねw

f:id:arakaji-yuu:20151103184903j:plain

f:id:arakaji-yuu:20151103184857j:plain

自分の場合こういう懇親会に参加するのは若干の人見知りが出てしまうので苦手なんですが、今回は登壇者の一人となったおかげもあって、スタッフの方や同じ九州事例Tracで発表をしていた方、また自分の発表を聞いて質問してきてくれる方などもいてくれて、人見知りでも懇親会を大いに楽しめて色んな人と出会う事ができました。

今回のイベントを運営してくれた方々、自分を発表者に推薦してくれた先輩方に本当に感謝です!!

さいごに

今回このJAWS Festa Kyusyu 2015に参加して得たことは3つ。

  • 発表は大変だけど、リターンも多いのでこれからも機会があれば挑戦したい!
  • 懇親会で自分の発表を聞いていただいた方に「あの発表が出来るくらいならAWS 認定ソリューションアーキテクト – アソシエイトぐらいならすぐ取れるよ!」といって頂いたので真に受けて取りたい!!
  • 起業に成功してIPOすると、旅人になれるらしい!!!

ではでは〜^^/

RackサーバーのPumaについて調べてみる

f:id:arakaji-yuu:20150803143727p:plain

はじめに

いま開発中のRailsアプリケーションのRackサーバーは最初Unicornを使っていたのですが、諸々の事情でPumaの方を使いたいということになった。 まだリリースもしていないのでやるなら早めに変えちゃおうということでPumaについて調べてみた。

Pumaとは

Pumaとはスピードと並列性を追求したRubyのWebサーバーです。 RubyでWebサーバーを作るときの標準となっているRackに対応したライブラリになっています。

スレッドベースのWebサーバー

Pumaではリクエストの並列処理を実現するためにスレッドを利用しています。 リクエストを処理するためのスレッドを予めスレッドプールに指定した数だけ用意しておきます。リクエストが来るとそのスレッドに処理を任せることでスレッドベースの並列処理を行っています。

Rubyの処理系について

Pumaではスレッド用いるため、Rubyの処理系はRubinusやJRubyを推奨していますが、MRI(Ruby標準の処理系)でも利用することが可能です。

MRIにおけるスレッドの扱い

MRIでのスレッドはGlobal Interpreter Lockという機能によって利用が制限されています。 Global Interpreter Lockとは「同時には一つのスレッドしか動かないようにする」というものです。

たとえばRubiusのようにスレッドによる並列処理をサポートしている処理系では3つのスレッドを立ち上げて処理を行った場合、同時に処理をおこないます。 ただしMRIはGlobal Interpreter Lockのよって3つのスレッドを立ち上げて処理を行っても一度に一つのスレッドしか処理をおこないません。1つのスレッドが処理をおこなっている最中にBlocking IO(ファイルやの書き込みやTwitterAPIを叩くなど)によって待ち時間が発生したタイミングで別スレッドに切り替えて処理を進めます。

使い方

起動

Pumaを起動する場合、以下のコマンドを実行します。

$ bundle exec puma

railsの場合、以下のコマンドでも実行可能です。

$ bundle exec rails s Puma

もしサーバーをデーモンとして実行したい場合は-dオプションを付けましょう

$ bundle exec puma -d

設定ファイルを指定する場合は-Cオプションのあとに設定ファイルへのパスを指定します。

$ bundle exec puma -C config/puma.rb

停止

Pumaを停止するにはプロセスに対してQUITシグナルを送ります。 rails s Pumaで起動した場合のデフォルトのpidファイルはtmp/pids/server.pidにありますので、そこに記載されているプロセスIDに対してシグナルを送信します

$ kill -QUIT `(cat tmp/pids/server.pid)`

設定ファイルconfig/puma.rbを指定して起動した場合、その設定ファイルから*.pidファイルを探せるのでpumactlというコマンドを使って簡単に停止することもできます。

$ bundle exec pumactl halt

再起動

Pumaの再起動はhot restartに対応しています。 hot restartとはnginxやunicornと同様にサーバーのソケットを開いたままリスタートすることを可能にします。それにより、ユーザーからのリクエストを待たせる事なくサーバーを再起動して新しいバージョンのアプリケーションに切り替える事ができます。

hot restartするにはpumaのプロセスに対してSIGUSR2シグナルを送信します。

$ kill -SIGUSR2 `(cat tmp/pids/server.pid)`

設定ファイルを指定した実行した場合、pumactlで再起動をかけることも出来ます。

$ bundle exec pumactl restart

設定ファイル

puma起動時のオプションの指定である程度カスタマイズできるがやはり設定ファイルに書いて起動する方が管理しやすいです。 pumaの設定ファイルでなにをどう設定できるかまとめておきます。

ちなみに設定ファイルのサンプルはpumaのgithubレポジトリpuma/examples/config.rbから手に入ります。

environment

pumaをどの環境で動作させるかを指定します。デフォルトは'development'になっています。 railsで使う場合は環境変数RAILS_ENVを直接environmentに指定するのが良いと想います。

# Set the environment in which the rack's app will run. The value must be a string
#
# The default is "development".
#
# environment 'production'
environment ENV['RAILS_ENV'] # Railsで使う場合

daemonize

rackサーバーをデーモンにして起動するかどうかを設定します。

# Daemonize the server into the background. Highly suggest that
# this be combined with "pidfile" and "stdout_redirect".
#
# The default is "false".
#
# daemonize
# daemonize false
daemonize true

pidfile

pidファイルを配置するパスを指定します。 Railsの場合、tmp/pids/puma.pidに配置するほうが良いと思います。

# Store the pid of the server in the file at "path".
#
# pidfile '/u/apps/lolcat/tmp/pids/puma.pid'
pidfile "#{Dir.pwd}/tmp/pids/puma.pid"

state_path

サーバー情報を記載したstateファイルを配置するパスを指定します。 stateファイルはpumactlコマンドでサーバーを操作するのに使用します。 railsの場合、特別このようなファイルを配置するディレクトリはないので今回はtmp/pids/以下に配置しておきます。

# Use "path" as the file to store the server info state. This is
# used by "pumactl" to query and control the server.
#
# state_path '/u/apps/lolcat/tmp/pids/puma.state'
state_path "#{Dir.pwd}/tmp/pids/puma.state"

Cluster mode

クラスタモードとは複数のワーカープロセスを起動し、そのプロセスそれぞれでスレッドプールを持ちリクエストを処理する仕組みです。 ワーカープロセスの数は以下のように指定します。 Workerの数をマシンが持つCore数を超えないように気をつけて下さい。

# === Cluster mode ===
# How many worker processes to run.
#
# The default is "0".
#
workers 2

Thread Pool

Pumaはスレッドによってリクエストを処理します。スレッドをスレッドプールに貯めておく数の下限から上限を指定することが出来ます。

# Configure "min" to be the minimum number of threads to use to answer
# requests and "max" the maximum.
#
# The default is "0, 16".
#
# threads 0, 16
threads 16, 16

bind

サーバーをどのように接続するかをURIで指定できます。 シンプルにTCPで接続する場合tcp://0.0.0.0:80、またWebサーバーの前段にnginxをなどを置き、そこからUNIX Socket経由で接続する場合はunix:///var/run/puma.sockのように指定します。

# Bind the server to "url". "tcp://", "unix://" and "ssl://" are the only
# accepted protocols.
#
# The default is "tcp://0.0.0.0:9292".
#
# bind 'tcp://0.0.0.0:9292'
# bind 'unix:///var/run/puma.sock'
# bind 'unix:///var/run/puma.sock?umask=0111'
# bind 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert'
bind 'unix:///var/share/sockets/puma.sock'

その他、なにが設定可能か調べるには

上記で指定したこと以外にも設定可能な項目はあります。 それを調べるには設定ファイルのサンプルか、設定ファイルのDSLが定義されたファイルを読んで探してみると大体何ができるか把握出来ます。

参考URL

https://github.com/puma/puma

slimからJSの世界にデータをjsonで渡す

いまWebのフロントエンド開発において、JSで一部のHTMLを動的に構築することが増えてきた。 JSでデータからHTMLを構築する場合、そのデータの部分はやっぱりjsonの方が扱いやすい。

自分はRailsのテンプレートエンジンにslimを使っているので、slimでJSの世界にjsonを渡す方法を考えたので書いておく。

htmlのdata-attributeにjsonを渡す

こんな感じ。

div.data-getter data-getter=@value.to_json

javascript:
  var value = JSON.parse($('.data-getter').attr('data-getter'));

jsにデータ受け取り用のglobal変数を作って、そこに渡す

こんな感じ。

javascript:
  DataGetter = {};
  DataGetter.value = #{raw @value.to_json}