株式会社クリアコード > ククログ

ククログ


OSS Gate大阪ワークショップ2017-02-25を開催 #oss_gate

2017年2月25日にファーストサーバさんOSS Gate大阪ワークショップを開催しました。初の大阪開催です!

集合写真

参加者は26名で東京開催並の規模になりました。大阪だけでなく、神戸・京都など近隣の人たちも集まっていました。

今回は進行の様子を動画に撮ることにチャレンジしました。撮影は@yasulabで、東京から日帰りで参加しました。ありがとうございます!

音声面での課題はありますが、録音機材の整備や字幕の追加などでカバーできそうです。ワークショップの最初の「OSS Gateの紹介」部分を字幕付きで公開しているので、雰囲気を知りたい方は確認してみてください!

今回のワークショップもビギナー・メンターともに楽しんで参加していたようです。次回も参加するという方が多かったので、次回も楽しみですね!

次回の関西でのワークショップ開催は4月になりそうです。興味のある方はチャットに参加してください。最新情報を入手できます。

現在は「OSS Gateワークショップ」は東京・札幌・大阪で開催しています。自分たちの地域でも開催したい!という方はチャットで相談しましょう!

2017-03-01

Fluentd v0.14.13で追加されたコマンドのご紹介

Fluentd v0.14.13が2017-02-27にリリースされていました。新しいコマンドが2つ追加されたのでご紹介します。

  • fluent-plugin-config-format
  • fluent-plugin-generate

fluent-plugin-config-format

プラグインの設定をいくつかのフォーマットで出力するコマンドです。 README.mdを書くのを楽にしたりコマンドラインからプラグインの設定値の意味を調べるためのものです。 Fluentd v0.12.16でプラグインの設定をコマンドラインから確認する方法で紹介したものの実装を改善して使いやすくしました。

$ fluent-plugin-config-format --help
Usage: fluent-plugin-config-format [options] <type> <name>

Output plugin config definitions

Arguments:
        type: input,output,filter,buffer,parser,formatter,storage
        name: registered plugin name

Options:
        --verbose                    Be verbose
    -c, --compact                    Compact output
    -f, --format=FORMAT              Specify format. (markdown,txt,json)
    -I PATH                          Add PATH to $LOAD_PATH
    -r NAME                          Load library
    -p, --plugin=DIR                 Add plugin directory

以下のコマンドは同じ意味です。

$ fluentd --show-plugin-config input:tail
$ fluent-plugin-config-format --format=txt input tail

plugin helperや Fluent::Plugin::Output の設定についてはdocs.fluentd.orgへのリンクにしたいところですが、2017年2月某日時点ではまだページがないので、リンクを生成することができていません。 ドキュメントが書かれたら、リンクを追加したいと考えています。

fluent-plugin-generate

新規プラグインを開発するときに使用するテンプレートを生成するためのコマンドです。 これまでは、既存のプラグインからコピーしたり、公式のドキュメントからコピーしたりしていましたが、このコマンドを使うことによって、これまでよりも簡単にプラグインの雛形を生成することができるようになりました。

$ fluent-plugin-generate --help
Usage: fluent-plugin-generate [options] <type> <name>

Generate a project skeleton for creating a Fluentd plugin

Arguments:
        type: input,output,filter,parser,formatter
        name: Your plugin name

Options:
        --[no-]license=NAME          Specify license name (default: Apache-2.0)

例えば、Zulipに出力するプラグインを作成するときは以下のように利用します。

$ fluent-plugin-generate output zulip
License: Apache-2.0
        create Gemfile
        create README.md
        create Rakefile
        create fluent-plugin-zulip.gemspec
        create lib/fluent/plugin/out_zulip.rb
        create test/helper.rb
        create test/plugin/test_out_zulip.rb
Initialized empty Git repository in /tmp/fluent-plugin-zulip/.git/

このように、必要なファイルが一通り生成されるのですぐに開発を始めることができます。 ユニットテストにはFluentd本体と同じ test-unit を使用しています。 ただし、このコマンドではFluentd v0.12以前のAPIを使用したプラグインを開発するためのファイルを生成することはできません。

fluent-plugins-nursery/fluent-plugin-zulip はこのコマンドを使用して開発を始めました。 README.mdのConfigurationの項は fluent-plugin-config-format を使用して生成しました。

まとめ

Fluentd v0.14.13で追加された2つの新しいコマンドについて紹介しました。 他の変更点についてはChangeLogを参照してください。

タグ: Fluentd
2017-03-09

MozillaのBugzillaへのパッチのsubmitのやり方

はじめに

MozillaによるFirefoxやThuderbirdの開発は基本的にBugzillaのやり取りにより行われています。そのため、GitHubでのやり取りに比べとっつきにくい印象がどうしても拭えません。MozillaのBugzillaでの開発プロセスを一通り行ったのでまとめます。 前回の記事 は「macOS Printing」や「macOS printToFile PDF」などで検索して引っかかったBugにsubmitしたパッチを解説しました。 今回はそのパッチをsubmitしてmozilla-centralにコミットされるまでの流れを追います。

Bugzillaでのやり取り

Bugzillaでは以下の図のようなやり取りを通じて開発が進められます。*1

review process

Mozillaの開発では基本的にパッチは何らかのBugに紐づけられるものです。 Bugを立てないことにはパッチのレビューをしてもらうことはできません。

準備

まずは直面した問題がBugになっていないかを確認します。まずはキーワードにより検索します。該当のBugがあればこのBugの作業がしたいというコメントを残して権限のある人にAssignしてもらいます。

以降ではprintToFile is busted on Mac | Mozilla Bugzillaでのやり取りを元に解説していきます。

パッチの作成

Bugにアサインされるといよいよパッチをsubmitするための準備が整います。 StatusはNEWのままで問題ないようです。

レビューに出す

MozillaのBugzillaでのレビューはreviewして欲しい人に対してreviewフラグを立てることにより始まります。また、レビューフラグを立ててもreviewフラグが立っている人が忙しいなどの理由で別の人にreviewフラグが移されることもあります。printToFile is busted on Mac | Mozilla Bugzillaでのやり取りではComment 19のようにreviewフラグが別に人に移譲されています。

パッチのコミット

レビューをめでたく通過した場合は、mozillaのリポジトリにコミットしてもらう必要があります。通常はコミット権はないのでcheckin-neededキーワードをkeywordに追加します: https://bugzilla.mozilla.org/show_bug.cgi?id=675709#c19

このcheckin-neededキーワードが追加されていないとレビューには通っても永久にmozillaのリポジトリにコミットされないことに注意してください。

Mozillaの古いWikiではこの段階で既にmozilla-centralへのコミットがなされると書かれていることがありますが、現在はmozilla-inboundというリポジトリにまずはコミットされます。

printToFile is busted on Mac | Mozilla Bugzillaでのやり取りでは一旦review+がもらえましたが、inboundでのビルド失敗により差し戻されています。

執筆現在のinboundサーバーのmacOSのワーカーが10.7のため、未定義となってしまった定数が出てしまったようです。

ステータスがFIXEDになればめでたく該当Bugでの作業は終了です。

まとめ

MozillaのBugzillaでの作業をどのように行うかをprintToFile is busted on Mac | Mozilla BugzillaのBugを元に解説を試みました。GitHubによる開発プロセスになれた開発者にはとっつきにくい印象がありますが、GitHubができるよりも前から開発が続いているソフトウェアの開発プロセスを体験してみるのはいかがでしょうか。

*1 以降は https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/How_to_Submit_a_Patch に基づいて解説します

2017-03-10

Apache Arrow C++の使い方:配列の作り方

Apache Arrowというデータ分析に特化したインメモリーのデータ操作ライブラリーがあります。

Apache Arrowは多くのシステムで使われることを目指しています。そうなることで各システム間でデータ交換しやすくなるからです。現時点では、Java、C++、JavaScriptは同じ仕様をそれぞれの言語で実装しています。Python、RubyにはC++のバインディングがあり、C++での実装をPython、Rubyで使えます。たとえば、Rubyでの使い方は名古屋Ruby会議03:Apache ArrowのRubyバインディングをGObject Introspectionでを参照してください。

このようにApache Arrowにはいくつかの実装がありますが、ここでは何回かにわけてC++実装の使い方を紹介します。

配列

Apache Arrowはカラム指向のデータ構造になっています。カラム指向の方が高速にデータ分析処理できるからです。

カラム指向のデータ構造というのは、1つのレコード(レコードには複数のカラムがある)をレコード単位で持つのではなく、カラム単位で持つデータ構造です。Apache Arrowのサイトの「Performance Advantage of Columnar In-Memory」に図があるのでピンとこない人はその図を参照してください。

カラム指向のデータ構造にするために、Apache Arrowでは配列が主なデータ構造になります。32bit整数のカラムも配列で表現しますし、文字列のカラムも辞書のカラム(Pythonで言えばdict、Rubyで言えばHashで、Apache Arrowは辞書のような複合型もサポートしている)も配列で表現します。

32bit整数のように固定長データのカラムを配列で表現するのはイメージしやすいでしょう。単に固定長(32bit整数なら4バイト)の領域をレコード数分だけ連続して確保してそこに値を詰めていけばよいです。

一方、文字列のような可変長データや辞書のような複合型をどのように配列で表現するかはイメージしにくいかもしれません。詳細はおいおい紹介しますが、たとえば、文字列は2本の配列で表現します。1つ目の配列には文字列が連続して詰まっています。もう1つの配列にはどこからどこまでが1つの文字列かという位置情報が詰まっています。たとえば、["abc", "d", "ef"]という文字列カラムは次のように表現します。

data = ["a", "b", "c", "d", "e", "f"]
offsets = [
  0, # 0番目のカラムの値の開始オフセット→data[0] == "a"
  3, # 0番目のカラムの値の長さ→data[0] + data[1] + data[2] == "abc"
  3, # 1番目のカラムの値の開始オフセット→data[3] == "d"
  1, # 1番目のカラムの値の長さ→data[3] == "d"
  4, # 2番目のカラムの値の開始オフセット→data[4] == "e"
  5, # 2番目のカラムの値の長さ→data[4] + data[5] == "ef"
]

このような構造になっていると定数時間で目的のカラムの値にアクセスできますし、データが局所化されているので連続してアクセスするときも高速です。(データ分析時は集計処理やフィルター処理をしますが、そのようなときは連続してアクセスします。)

このようにApache Arrowはいろいろな型のカラムを配列で表現します。配列は変更できないという制約があります。この制約があるため、少しずつ配列を作っていくということはできません。作るときは一気に作らないといけません。(この制約があるので、配列間でデータを共有でき、サブ配列の作成コストが安くなるというメリットがあるのですが、そのあたりはおいおい紹介します。)

配列を作るのが大変そうと感じるかもしれませんが、配列を作ることを支援するために配列ビルダーが提供されているので、それを使えばそれほど大変ではありません。

配列ビルダー

配列ビルダーとは配列を作るオブジェクトです。配列を作るときは配列ビルダーを使うのが便利です。

配列ビルダーを使う基本的な流れは次の通りです。

  1. 配列ビルダーを作る。
  2. Append()で要素を追加する。(要素がNULLの場合はAppendNull()で要素を追加する。)
  3. Finish()でそれまで追加した要素で配列を作る。

たとえば、真偽値の配列を作るには次のようにarrow::BooleanBuilderを使います。

#include <iostream>
#include <arrow/api.h>

int
main(int argc, char **argv)
{
  std::shared_ptr<arrow::Array> array;
  {
    // 真偽値の配列データを確保する領域
    auto memory_pool = arrow::default_memory_pool();
    // 真偽値の配列を作成するビルダー
    arrow::BooleanBuilder builder(memory_pool);
    // 1つ目の要素はtrue
    builder.Append(true);
    // 2つ目の要素はfalse
    builder.Append(false);
    // 3つ目の要素はtrue
    builder.Append(true);
    // 3要素の配列を作成
    builder.Finish(&array);
  }

  // 内容を確認
  // 出力:
  // 0:true
  // 1:false
  // 2:true
  for (int64_t i = 0; i < array->length(); ++i) {
    auto boolean_array = static_cast<arrow::BooleanArray *>(array.get());
    std::cout << i << ":";
    // i番目の値を出力
    std::cout << (boolean_array->Value(i) ? "true" : "false");
    std::cout << std::endl;
  }

  return 0;
}

Apache Arrowはpkg-configに対応しているのでビルド方法は次の通りです。

% g++ -o boolean-array boolean-array.cpp $(pkg-config --cflags --libs arrow)

実行すると次のように[true, false, true]という配列を作れたことを確認できます。

% ./boolean-array
0:true
1:false
2:true

NULL配列や共用体配列のようにすぐに作れる配列には配列ビルダーはありませんが、基本的には配列ビルダーを使って配列を作ります。

まとめ

Apache Arrowでの配列の位置付けと配列ビルダーを使った配列の作り方を紹介しました。

2017-03-15

Apache Arrowの(非公式)パッケージを公開

Apache ArrowのC++実装およびC++実装のCバインディング(Cで書かれたからC++実装を使うためのラッパー)のパッケージを公開しました。これにより簡単にApache Arrowを使えるようになります。C/C++だけでなく、Rubyからも簡単に使えるようになります。

なお、パッケージはApache Arrowプロジェクトが公式に提供しているものではなく、Apache Arrowプロジェクトの開発に参加している人が提供している非公式なものです。非公式なものですが、Apache Arrowについてもパッケージについてもよく知っている人が作っているものなので安心して利用できます。

対応プラットフォーム

以下のプラットフォーム用のパッケージを公開しました。

  • Debian GNU/Linux jessie
  • Ubuntu 16.04 LTS
  • Ubuntu 16.10
  • CentOS 7

それぞれのプラットフォームごとに利用方法を説明します。それぞれのセクションだけ(自分が使っているプラットフォームのセクションだけ)を読めば分かるように書いています。そのためそれぞれのセクションで重複した説明があります。

Debian GNU/Linux jessieとUbuntu 16.04 LTSとUbuntu 16.10

Debian GNU/Linux jessieとUbuntu 16.04 LTSとUbuntu 16.10でApache Arrowのパッケージを使う方法を説明します。最初のAPTリポジトリーを追加するところだけがDebian GNU/LinuxとUbuntuで違うだけでそれ以降は同じです。

まずApache Arrowのパッケージを提供しているAPTリポジトリー用のapt-lineを追加します。GroongaのAPTリポジトリーに相乗りしているので以下のapt-lineになります。

Debian GNU/Linux jessieの場合は、まず以下の内容の/etc/apt/sources.list.d/groonga.listを作成してapt-lineを追加します。

deb http://packages.groonga.org/debian/ jessie main
deb-src http://packages.groonga.org/debian/ jessie main

次にこのapt-lineで追加したAPTリポジトリーを使えるようにします。

% sudo apt update
% sudo apt install -y --allow-unauthenticated groonga-keyring
% sudo apt update

Ubuntuの場合は次のようにします。

% sudo apt install -y software-properties-common
% sudo add-apt-repository -y ppa:groonga/ppa
% sudo apt update

これでパッケージをインストールする準備ができました。以下はDebian GNU/Linux jessie、Ubuntu 16.04 LTS、Ubuntu 16.10で共通です。

Apache ArrowのC++実装を使う場合はlibarrow-devパッケージをインストールします。

% sudo apt install -y libarrow-dev

Cバインディングを使う場合はlibarrow-glib-devパッケージをインストールします。Cバインディングを使うと、Ruby、Lua、Go、Rustなどからも使えるようになります。Ruby、Lua、Go、Rustなどから使いたい場合はlibarrow-glib-devパッケージをインストールしてください。

% sudo apt install -y libarrow-glib-dev

RubyでApache Arrowを使う場合は、まずはRubyをインストールします。拡張ライブラリーを使うのでruby-devパッケージもインストールします。

% sudo apt install -y ruby ruby-dev

red-arrow gemをインストールするとRubyからApache Arrowを使えるようになります。

% sudo gem install red-arrow

以下はRubyの配列とApache Arrowの配列を変換する例です。

require "arrow"

counts = Arrow::UInt32Array.new([1, 2, 4, 8])
p counts.to_a # => [1, 2, 4, 8]

以下は↑と同じ内容の配列を2回にわけて/tmp/logs-stream.arrowに書き出す例です。Apache Arrowは効率のよいプロセス間のデータ交換の実現も大事にしているので、データの書き出しはよくある使い方です。

#!/usr/bin/env ruby

require "arrow"

fields = [
  Arrow::Field.new("count", Arrow::UInt32DataType.new),
]
schema = Arrow::Schema.new(fields)

Arrow::IO::FileOutputStream.open("/tmp/logs-stream.arrow", false) do |output|
  Arrow::IPC::StreamWriter.open(output, schema) do |writer|
    counts1 = [1, 2]
    arrow_counts1 = Arrow::UInt32Array.new(counts1)
    record_batch = Arrow::RecordBatch.new(schema, counts1.size, [arrow_counts1])
    writer.write_record_batch(record_batch)

    counts2 = [4, 8]
    arrow_counts2 = Arrow::UInt32Array.new(counts2)
    record_batch = Arrow::RecordBatch.new(schema, counts2.size, [arrow_counts2])
    writer.write_record_batch(record_batch)
  end
end

それでは、このデータをLuaから読み出してみましょう。LuaからApache Arrowを使うにはLGIを使います。

% sudo apt install -y luarocks
% sudo luarocks install lgi

以下のコードでRubyで書き出したデータを読み込めます。MemoryMappedFileというオブジェクトを使って読み込んでいるのでゼロコピー(コピーなし)でデータを読み込んでいるので効率的です。

local lgi = require 'lgi'
local Arrow = lgi.Arrow
local ArrowIO = lgi.ArrowIO
local ArrowIPC = lgi.ArrowIPC

local input = ArrowIO.MemoryMappedFile.open("/tmp/logs-stream.arrow", ArrowIO.FileMode.READ)
local reader = ArrowIPC.StreamReader.open(input)

local i = 0
while true do
  local record_batch = reader:get_next_record_batch()
   if not record_batch then
    break
  end

  local column = record_batch:get_column(0)
  for j = 0, record_batch:get_n_rows() - 1 do
    print("record_batch["..i.."]["..j.."] = " .. column:get_value(j))
    -- record_batch[0][0] = 1
    -- record_batch[0][1] = 2
    -- record_batch[1][0] = 4
    -- record_batch[1][1] = 8
  end

  i = i + 1
end

input:close()

実行すると次のように表示されます。きちんと読み込めていますね。

record_batch[0][0] = 1
record_batch[0][1] = 2
record_batch[1][0] = 4
record_batch[1][1] = 8

次はPythonのPandasで作ったデータを書き出してRubyから読み込んでみましょう。

PythonからApache Arrowを使うにはpyarrowをインストールします。

% wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh
% bash Miniconda3-latest-Linux-x86_64.sh
% source ~/.bashrc
% conda install -y --channel conda-forge pyarrow

Pandasで作ったデータをApache ArrowのRecordBatchに変換してファイルに書き出します。

#!/usr/bin/env python

import pandas as pd
import numpy as np
import pyarrow as arrow

df = pd.DataFrame({'count': [1, 2, 4, 8]})
batch = arrow.RecordBatch.from_pandas(df)
sink = arrow.io.OSFile("/tmp/logs.arrow", "w")
writer = arrow.ipc.FileWriter(sink, batch.schema)
writer.write_batch(batch)
writer.close()
sink.close()

このデータを読み込むRubyのコードは次の通りです。

#!/usr/bin/env ruby

require "arrow"

Arrow::IO::MemoryMappedFile.open("/tmp/logs.arrow", :read) do |input|
  Arrow::IPC::FileReader.open(input) do |reader|
    reader.each do |record_batch|
      record_batch.each do |record|
        p record[:count]
        # 1
        # 2
        # 4
        # 8
      end
    end
  end
end

次のように出力されるので正しく読み込めています。

1
2
4
8
CentOS 7

CentOS 7でApache Arrowのパッケージを使う方法を説明します。

まずApache Arrowのパッケージを提供しているYumリポジトリーを追加します。GroongaのYumリポジトリーに相乗りしているので以下のように追加します。

% sudo yum install -y http://packages.groonga.org/centos/groonga-release-1.2.0-1.noarch.rpm

これでパッケージをインストールする準備ができました。

Apache ArrowのC++実装を使う場合はarrow-develパッケージをインストールします。

% sudo yum install -y arrow-devel

Cバインディングを使う場合はarrow-glib-develパッケージをインストールします。Cバインディングを使うと、Ruby、Lua、Go、Rustなどからも使えるようになります。Ruby、Lua、Go、Rustなどから使いたい場合はarrow-glib-develパッケージをインストールしてください。

% sudo yum install -y arrow-glib-devel

RubyでApache Arrowを使う場合は、まずはRubyをインストールします。

% sudo yum install -y git gcc openssl-devel readline-devel zlib-devel
% git clone https://github.com/rbenv/rbenv.git ~/.rbenv
% echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
% echo 'eval "$(~/.rbenv/bin/rbenv init)"' >> ~/.bash_profile
% source ~/.bash_profile
% git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
% rbenv install 2.4.1

red-arrow gemをインストールするとRubyからApache Arrowを使えるようになります。

% gem install red-arrow

以下はRubyの配列とApache Arrowの配列を変換する例です。

require "arrow"

counts = Arrow::UInt32Array.new([1, 2, 4, 8])
p counts.to_a # => [1, 2, 4, 8]

以下は↑と同じ内容の配列を2回にわけて/tmp/logs-stream.arrowに書き出す例です。Apache Arrowは効率のよいプロセス間のデータ交換の実現も大事にしているので、データの書き出しはよくある使い方です。

#!/usr/bin/env ruby

require "arrow"

fields = [
  Arrow::Field.new("count", Arrow::UInt32DataType.new),
]
schema = Arrow::Schema.new(fields)

Arrow::IO::FileOutputStream.open("/tmp/logs-stream.arrow", false) do |output|
  Arrow::IPC::StreamWriter.open(output, schema) do |writer|
    counts1 = [1, 2]
    arrow_counts1 = Arrow::UInt32Array.new(counts1)
    record_batch = Arrow::RecordBatch.new(schema, counts1.size, [arrow_counts1])
    writer.write_record_batch(record_batch)

    counts2 = [4, 8]
    arrow_counts2 = Arrow::UInt32Array.new(counts2)
    record_batch = Arrow::RecordBatch.new(schema, counts2.size, [arrow_counts2])
    writer.write_record_batch(record_batch)
  end
end

それでは、このデータをLuaから読み出してみましょう。LuaからApache Arrowを使うにはLGIを使います。

% sudo yum install -y lua-devel luarocks gobject-introspection-devel
% sudo luarocks install lgi

以下のコードでRubyで書き出したデータを読み込めます。MemoryMappedFileというオブジェクトを使って読み込んでいるのでゼロコピー(コピーなし)でデータを読み込んでいるので効率的です。

local lgi = require 'lgi'
local Arrow = lgi.Arrow
local ArrowIO = lgi.ArrowIO
local ArrowIPC = lgi.ArrowIPC

local input = ArrowIO.MemoryMappedFile.open("/tmp/logs-stream.arrow", ArrowIO.FileMode.READ)
local reader = ArrowIPC.StreamReader.open(input)

local i = 0
while true do
  local record_batch = reader:get_next_record_batch()
   if not record_batch then
    break
  end

  local column = record_batch:get_column(0)
  for j = 0, record_batch:get_n_rows() - 1 do
    print("record_batch["..i.."]["..j.."] = " .. column:get_value(j))
    -- record_batch[0][0] = 1
    -- record_batch[0][1] = 2
    -- record_batch[1][0] = 4
    -- record_batch[1][1] = 8
  end

  i = i + 1
end

input:close()

実行すると次のように表示されます。きちんと読み込めていますね。

record_batch[0][0] = 1
record_batch[0][1] = 2
record_batch[1][0] = 4
record_batch[1][1] = 8

次はPythonのPandasで作ったデータを書き出してRubyから読み込んでみましょう。

PythonからApache Arrowを使うにはpyarrowをインストールします。

% wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh
% bash Miniconda3-latest-Linux-x86_64.sh
% source ~/.bashrc
% conda install -y --channel conda-forge pyarrow

Pandasで作ったデータをApache ArrowのRecordBatchに変換してファイルに書き出します。

#!/usr/bin/env python

import pandas as pd
import numpy as np
import pyarrow as arrow

df = pd.DataFrame({'count': [1, 2, 4, 8]})
batch = arrow.RecordBatch.from_pandas(df)
sink = arrow.io.OSFile("/tmp/logs.arrow", "w")
writer = arrow.ipc.FileWriter(sink, batch.schema)
writer.write_batch(batch)
writer.close()
sink.close()

このデータを読み込むRubyのコードは次の通りです。

#!/usr/bin/env ruby

require "arrow"

Arrow::IO::MemoryMappedFile.open("/tmp/logs.arrow", :read) do |input|
  Arrow::IPC::FileReader.open(input) do |reader|
    reader.each do |record_batch|
      record_batch.each do |record|
        p record[:count]
        # 1
        # 2
        # 4
        # 8
      end
    end
  end
end

次のように出力されるので正しく読み込めています。

1
2
4
8

まとめ

Apache ArrowをC/C++/Ruby/Lua/Go/Rustなどから使いやすくするためにApache ArrowのC++実装とそのCバインディングのパッケージを公開しました。

Apache Arrowを使っていろんな言語をデータ分析に活用してください。

2017-03-23

OSS Gate東京ワークショップ2017-03-25を開催 #oss_gate

2017年3月25日にクラウドワークスさんOSS Gate東京ワークショップを開催しました。東京でのワークショップ開催は今回で8回目です。今回は18名の参加でした。当日無断欠席率は30%くらいでいつも(50%くらい)より少なかったです。おぉ。今回はいつもとなにが違ったのだろう。

Untitled (写真は@koyhogeさんが撮ってくれました。)

参加者の感想は次の通りです。(増えたら追記します。)

ここではワークショップ運営視点でまとめます。

今回のチャレンジ

今回は1人のメンターで4人のビギナーをサポートすることにチャレンジました。より少ないメンターでより多くのビギナーをサポートできるとワークショップ開催が楽になるからです。

チャレンジしてみた結果は次の通りです。

よかったこと:

  • ビギナーのつながりができやすそう。
    • ワークショップ後もチャットでやりとりを続けているのはこのグループのみなんだけど、関係があるのかも。

課題:

  • 誰でもできるわけではなさそう。(慣れた人じゃないと難しそう。)
  • ワークショップの時間の配分の調整が必要そう。(従来の体制より「ふりかえり」の時間が長くなる。)

「ビギナーのつながりができやすそう」というのは「Gateをくぐった後もOSSの開発を継続して欲しい」というOSS Gateの目指したいことにプラスになりそうなので、このチャレンジの結果を次のワークショップ開催にも活かせるとよさそうです。

(ここから参加したことがある人じゃないとわからなそうな書き方。)

2人で4人のビギナーをサポートするという従来の比率(従来は1人で2人のビギナーをサポート)はそのままで、全部このスタイルで実施、というのを試してみるとよさそうです。そうすれば課題は解決できそうです。

なお、「ふりかえり」の時間が長くなるのは前半パートの終わりのときだけです。前半パートの終わりのときの「ふりかえり」は4人を順にやるので従来のやり方(2人ずつ並列でやる)より2倍時間がかかります。一方、後半パートの終わりのときの「ふりかえり」は1日分じゃなくて後半パート分だけでよい(前半パートの終わりのときにみんな前半分を聞いているから)ので、従来のやり方(前半と後半を2人ずつ並列でやる)と同じくらいの時間になるはずです。

(ここまで参加したことがある人じゃないとわからなそうな書き方。)

今回の気づき

お昼休憩のとき、なかなか「ビギナー」経験者が「メンター」にならないのはどうしてだろうと話しました。ビギナーから「メンター」という単語はすごそうな人なイメージがあって「ビギナー」を1回やっただけだとムリムリ!という気持ちになるというような話を聞きました。たしかにそうかもしれません。

次回からは「サポーター」など「メンター」ではない名前を使おうと検討中です。

なお、次回は5月27日開催です。

まとめ

3月25日に5回目のOSS Gateワークショップを開催しました。

今回は次のことにチャレンジしました。

  • 1人のメンターで4人のビギナーをサポートする

まだまだ課題はあるものの磨けばよくなりそうな雰囲気を感じました。

3月30日には姉妹(?)イベントであるOSS Gate東京ミートアップ2017-03-30があります。OSSの開発に興味のある方はこちらもチェックしてみてください。

2017-03-29

«前月 最新記事 翌月»
タグ:
年・日ごとに見る
2008|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|