A Day In The Boy's Life -29ページ目

A Day In The Boy's Life

とあるエンジニアのとある1日のつぶやき。

今風のWebサービスを使っていると重たい処理などを行う際に画面上にプログレスバーが表示されたりして、ユーザーのイライラを緩和する措置が取られたりしています。

特に重たいファイルをアップロードする場合などにプログレスバーが表示されれば進捗もわかり、ユーザー的にも後どれぐらい待てばいいのかといった状況が把握しやすくなります。

 

今回は、PHPのキャッシュモジュールとして使われているAPC とjQueryUIのProgressbarウィジット を使って、ファイルアップロード時にプログレスバーを表示するというプログラムを書いてみたいと思います。

 

 

 

プログレスバーのイメージとAPCの環境設定

 

 

 

今回実装するプログレスバーのイメージは下記のようなものです。


file_upload_progress

 

 

 

進捗率の表示などはオリジナルな部分はありますが、ファイルを指定してからアップロード完了までの間、画面上にプログレスバーが伸びていき状況が把握できるようになっています。

 

 

通信は非同期に行われるため画面遷移が無く、ファイルアップロード画面だけで処理が完結できるようになっています。

 

今回の実行環境はPHP5.3.3、APCは3.1.13を使っています。

 

APC導入に関して詳細は書きませんが、PHPの設定ファイル(php.ini)に下記の設定項目を追加しておきます。

 

apc.rfc1867 = On

 

 

これにより、ファイルアップロードの進捗ハンドラが有効になります。

 

詳細は、マニュアル にも記載があるので確認するとよいかもしれません。


 

ファイルアップロード時にプログレスバーを表示するプログラム

 

今回作成したプログラムは、3つに分かれています。

 

1つ目がファイルアップロード画面のプログラム、2つ目が送られたファイルのチェックやアップロード後の処理を行うプログラム、3つ目が進捗管理用のプログラムです。

 

順番に見て行きますが、1つ目のファイルアップロード画面(index.php)は下記のようになっています。

 

 

<html>
<head>
<meta http-equiv='Content-Type' content='text/html;charset=utf-8'>
<link rel='stylesheet' href='//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css'>
<script src='//code.jquery.com/jquery-1.10.2.js'></script>
<script src='//code.jquery.com/ui/1.10.4/jquery-ui.js'></script>
<style type='text/css'>
.upload {
padding:10px;
}
#progressbar {
position: absolute;
margin: 10px;
width:500px;
}
#loading {
position: absolute;
left: 50%;
}
</style>
<script>
var timer = null;
var progressMeter = 0;
// ファイルアップロード
function formSubmit() {
$('#progressbar').progressbar({
value: false,
change: function () {
$('#loading').text($('#progressbar').progressbar('value') + '%');
}
});
var formData = new FormData();
formData.append('APC_UPLOAD_PROGRESS', $('#progress_key').val());
if ($('#uploadFile').val() !== '' ) {
formData.append('uploadFile', $('#uploadFile').prop('files')[0] );
}
timer = setInterval('progressBar()', 3000);
$.ajax('/upload.php', {
method: 'POST',
contentType: false,
processData: false,
data: formData,
dataType: 'text',
error: function (XMLHttpRequest, errorText) {
clearInterval(timer);
console.log(errorText);
},
success: function (res) {
clearInterval(timer);
if (res) {
// Uploadしたファイルのエラー内容を受信・出力
alert(res);
$('#progressbar').progressbar("destroy");
} else {
$('#progressbar').progressbar('value', 100);
location.href = 'index.php';
}
}
});
}
// 進捗割合の取得・表示
var progressBar = function () {
jqxhr = $.ajax('/progress.php', {
type: 'POST',
data: { APC_UPLOAD_PROGRESS: $('#progress_key').val() },
}).done(function (progressMeter) {
if (progressMeter) {
$('#progressbar').progressbar('value', parseInt(progressMeter));
}
});
}
</script>
</head>
<body>
<br />
<form  method='post' enctype='multipart/form-data' id='uploadForm'>
<input type='file' name='uploadFile' style='width:400px;' id='uploadFile' />
<input type='hidden' name='APC_UPLOAD_PROGRESS' id='progress_key' value='539e79fc9249f' />
<input type='button' value='アップロード' onClick='javascript:formSubmit();'>
<div id='progressbar'>
<div id='loading'></div>
</div>
</form>
</body>
</html>

 


まず、jQueryやjQuery UIのソースコードはホストとされているものを使っていますが、この辺は自信の環境にあるのであれば読込み方を適宜変更してください。

 

進捗の表示は、HTML内のIDがprogressbarのDIV要素にプログレスバーが、その中のloadingのDIV要素に進捗割合が表示されます。

 

表示処理しているjQueryのコードの箇所は、

 

  $('#progressbar').progressbar({
value: false,
change: function () {
$('#loading').text($('#progressbar').progressbar('value') + '%');
}
});

 

 

の部分となります。
valueに、進捗率を設定すればバーが100%に向けて伸びていきます。

 

厳密に言うと、「max」の項目を追加することで100%を幾つの数値にするか決められたりするので、valueで設定できるのは100までの数値とは限りません。

最初にfalseを設定しますが、これを設定すると先ほどのイメージの例の最初に表示されるような斜線のバーがぐるぐる回るようなアニメーションをするというだけで、あまり意味はないです。

「change」の設定項目はvalueの値が変化したときの処理を書きますが、画面上にその値を描画するように定義しています。

 

あとは、FormData()でフォームオブジェクトを作成し、APC_UPLOAD_PROGRESSの値とファイルデータをAjaxで送信しています。

 

APC_UPLOAD_PROGRESSは、マニュアルにも記載の通りこのパラメータがあればAPCはアップロードの進捗データを生成するようになります(このキーは、apc.rfc1867_name にて変更ができるみたいです)

ですので、APC_UPLOAD_PROGRESSの値をサーバーに送ることで、進捗データを生成させ、下記の進捗率を取得する関数でその値を受け取って画面上の割合を変化させています。

(詳細は、後述する進捗管理用のプログラムのところで触れています)

 

var progressBar = function () {
jqxhr = $.ajax('/progress.php', {
type: 'POST',
data: { APC_UPLOAD_PROGRESS: $('#progress_key').val() },
}).done(function (progressMeter) {
if (progressMeter) {
$('#progressbar').progressbar('value', parseInt(progressMeter));
}
});
}

 

 

続いて、送られたファイルのチェックやアップロード後の処理を行うプログラム(upload.php)ですが、この辺はシステム要件によってどんなチェックをするのかや、アップロードされたファイルをどこに保存するのかが変わってくるので、ここではかなり適当に書いています。

 

 

<?php
// 簡易的なエラーチェック
if (!empty($_FILES)) {
if (!empty($_FILES['uploadFile']['error'])) {
// エラーがあったら返すとか
echo $_FILES['uploadFile']['error'];
} else {
// アップロード成功したら適切な場所に保存するとか
move_uploaded_file($_FILES['uploadFile']['tmp_name'], "/tmp/" . $_FILES['uploadFile']['name']);
}
} else {
echo "Empty File";
}

 

 

最後は、進捗管理用のプログラム(progress.php)です。

 

 

<?php
$num = 0;
if (isset($_POST['APC_UPLOAD_PROGRESS'])) {
$status = apc_fetch('upload_' . $_POST['APC_UPLOAD_PROGRESS']);
if (isset($status['current'], $status['total'])) {
// 進捗計算
$num = strval(ceil($status['current'] / $status['total'] * 100));
}
}
echo $num;

 

 

こちらは、先ほど書いたようにAPC内のキャッシュデータから進捗データを読み取って計算して割合を返すということをしています。

 

キャッシュデータの読み込みは、APC_UPLOAD_PROGRESSの値によって行われますので、このキーはユーザーごとにユニークなものを割り振る必要があります

先ほどのindex.php内で「539e79fc9249f」という値で送信していますが、この値をユニークになるように設定し埋め込んでおく必要があります。

また、apc_fetchにて進捗データを読込む際に、「upload_」の接頭辞を使っていますが、これもデフォルトのものでapc.rfc1867_prefix の設定項目によって変更することが可能です。

apc_fetchで受け取る配列のtotalキーがファイルの合計容量、currentが現在受け取っているデータサイズとなるので、ここから進捗を計算しているということになります。

 

今回はファイルアップロードの進捗表示ということで書いてみましたが、進捗を返せばjQueryのProgressbarウィジットでプログレスバーを表示することはできるので、処理内で進捗計算して値を返すようにすれば、その他の処理でも進捗表示をさせることができたりしますので応用してみてもよいかもしれません。

 

 

 

 

 

 

 

 

 

別に採用関連の仕事をしているわけではないのですが、毎年募集する新人とかの選考には多少絡んできたりもして、エンジニアを採用する難しさって結構身にしみるようになってきました。

一緒に仕事をして行く上で人間性も大事だし、ただ仕事を任せる上での技術力や知識というのも大事だしというジレンマがあったりするわけです。

 

 

人を育てる風土を維持できるか

 

新入社員を採用する場合、会社側の立場としては即戦力を求めることはないかと思いますが、入社後の教育というものにどれだけの時間とお金をかけられるのかはその企業文化によってきたりもします。

 

入社後の数ヶ月の研修だけですぐに現場に飛ばされ、現場で仕事を覚えろといういわゆるOJTが一般的で、言ってしまえば人は辞めるもの担当者は代わるものとしてマニュアル化した教育をしているところもあれば、なるべく企業に根付いて欲しいと思い、研修期間を終わってもある程度じっくりと時間をかけて長い眼で人を育てていくところもあります。

 

こういうのも企業の業務形態や戦略的な面にも大きく左右され、下請けを使うなどアウトソースするところやオフショア開発などに傾倒しているところでは、そんなに教育に投資できないというところもあるかもしれませんし、そういった戦略をとって痛い目を見たところはやっぱり自社にちゃんと自分たちのサービスのコアがわかるエンジニアを育てないといけないとして、ちゃんと教育して囲い込むことをやっている企業もあるでしょう。

 

こういうのは企業文化レベルだけでなく、その時々の経営判断なんかでも大きく左右されるので、幾ら自部門で人を育てていこうという戦略を立ててもその風土を維持することが難しかったりもします。

 

そして、誰がその人を育てるのか、というのも大きな問題となります。

 

大きな組織で教育部門がしっかりしていればある程度の基礎レベルまでは引き上げられるでしょうけど、それでもその人がサービスの核となるエンジニアになるためには、より多くの知識と時間が必要になります。

その組織の中にはロールモデルとなる人が存在するかもしれませんが、その人を教育担当者にあてがうには多くの場合ためらわれることだと思います。

その人に教育をさせるよりすべきことが他に多々あるでしょうし、場合によってはその人が多くの時間を教育にとられることを嫌いモチベーションが下がるかもしれません。

 

また、以前に何度か書いていますが現在の業務環境だと失敗できないものが非常に多くなってきており、十分な経験を与えることが難しくなってきたりもしています。

 

経験を経てわかることも、その経験する機会が減少したことにより、幾ら人を育てていきたいと考えていても採用したエンジニアをうまく育てていけない状況にあったりするわけです。

これにはある程度の失敗を許容できる環境が無いといけませんし、周りの人たちもそれに耐えられる、対応できるようになっていなくてはなりません。

 

 

経験者か未経験者か

 

採用する対象者もこういった企業文化やそのときの戦略によって大きく変わってきます。

 

PCやプログラミングに関する知識が皆無でも人となりがよく、素直に聞いて成長していってくれればよいということであればそれほど大学のブランドや学部、何を研究してたのかといったことなんかそれほど気にしなくてもよいでしょうけど、なるべく早く業務に就けるようにするのであれば大学でやってきたレベルとはいえ、基礎知識がその後の教育に大きく左右されたりします。

 

よっぽどの熱意があったり、大きな研究室で時間を費やしていたとしても、エンジニアとして社会に出る多くの人たちの多くは業務で開発する能力として適合しないケースの方が多かったりします。

 

それは、プログラミングのスキルがあるというのと、開発業務が行えるというのは当然違っていて、悲しいかな多くのスキルは企業のルールや体制・役割によって潰されたり適合できない場合があるからです。

個人の趣味でやる分には最先端の技法やツールを使う分には何の問題もありませんが、企業内では酷くレガシー化したシステムも多数残っていたりして、むしろ個人としてやってきたスキルを活かせない持ち腐れ状態になる人もいるかもしれません。

技術一本でやっていきたいという人は、最初から独立するか研究室のようなそれだけをやれる環境を目指した方が良いかもしれませんが、一般的な企業の中ではその人の幾ら強みであろうとも、それだけをやらせるという余裕も無ければ許容もしてくれません。

 

大学で勉強してきたからといって即戦力になるとは企業の中のヒト的に誰も思っては無いけど、基礎レベルとして構造が理解できるかどうかって結構その後の教育にも大きく影響を与えてきたりもします。

 

未経験者は素直で吸収も早いかもしれませんが、根本的に開発における理系脳のようなものについてこれない人もよく見かけます。

暗記ができても応用できないという感じで、プログラミングの構文を覚えても仕様どおりに組み立てるという応用が全然できないという具合に。

 

そういう意味で当然経験者の方を優遇したりもするのですが、必ずしもチームにある空いているポジションというのはバリバリできる開発者ばかりというだけでなく、運用を組み立てたりユーザーとの業務調整や企画をする人など幅広いところで役割があるので採用側もどのポジションに人を入れるかで変わってくるところではあります。

 

全員4番打者で打順を組み立てる必要は無いですし、当然そんなことでチームがうまく回るわけでもなく、フルスタックエンジニアなんて要らない、ミドルだけまたはネットワークだけができれば十分と思っているところもあるわけなので、どのポジションの人を採用するかというのをきちんと考えておかないと、何でもできる人材像を勝手に描いてしまって、入社後のその人の能力とのギャップに組織が苦しむことになります。

 

 

まとめ

 

新卒採用にしろ、中途採用にしろ、社員として雇ってしまったからには日本文化的にその人を急に辞めさせることもできませんし、メンバーとそりが合わない人や期待したスキルを持っていないという状況で現場を混乱させることは避けたいところです。

 

ですが、履歴書や筆記試験や採用面談の少ない情報や短い時間の中でその判別をするのは凄く難しいことですので、ある程度企業側も期待することや許容範囲を決めておく必要はあると思います。

 

そういったときに、ちゃんと人を育てることができるのかや、今の体制の課題からどの役割を埋めて欲しいのかというその人のキャリアも含めてきちんと考えておかないと、何時まで経っても組織の課題は解決されずに無駄に人だけが増えてしまうということになってしまうのだと思います。

 

 

 

 

 

「とりあえずこれを優先度上げてやっといて」と上から言われたことは誰しもあるのではないでしょうか。

冷静に考えればその目的や効果というものがはっきりしないものの、取りあえず言われたからやらないと・・・と必死になって作り上げたものの大して使われずに終わるという経験も合わせてあるのではないかと思います。

 

こういうの無茶振りって言うんでしょうけど、もっと酷いものとして明らかに失敗することが目に見えているものやその場の思い付きを押し付けられることがあったりします。

 

最終的に無駄になるわけですから、モチベーションもかけられませんし案の定そうなった場合の徒労感が半端無いわけです。

 

要は上から仕事を降られて対応したものの結局は無駄に終わるというもので、こういったものは時間や労力の無駄というだけでなく、現場を混乱させ未来への投資機会を奪う結果にもなったりします。

 

現場の人間にとっては戦々恐々で、報告のたびに何言われるんだろうという不安に駆られたり、言われたところで「絶対思いつきだな」と思うものや「言いたいだけだろ」という不満も持つことになったりします。

 

 

無駄振りの怖さ

 

 

無駄振りされたものは最終的に何も残りません。

 

無茶振りでも何かしらの成果物ができたり、新たなサービスや仕組みが生まれたりすれば後で落ち着いたときに達成感というものも得られるかもしれませんが、無駄振りはその場の思いつきでしかなく、達成したところでその個人だけが満足するという結果しか得られません

 

また、思い付きであるが故に本人にも明確なビジョンを持っていないことが多く、そういうことを言い出す人にはそれなりに社会的権威や地位があったりして、それが邪魔して周りも聞くに聞けない状況になっていたりします。

 

言われたことの情報が少なすぎるために何を具体化すればいいのかわからず目的や効果、ゴールが見えないマイルストンの中でタスクを試行錯誤するしかなく仕事がとても非効率となったりします。

 

何とか形として成果を見せれば満足はしてくれるものの、それ以降の運用やブラッシュアップすることに当人の興味は薄く、言ったことはすぐ忘れられたりします。

 

そして形だけ出来上がったものが当然うまく回るわけも無くそのうち形骸化してすぐに仕組みは廃れていくわけですが、怖いのは本人がその頃に再度似たような仕組みを作るアイデアを持ち出したりするわけです。

「あれがうまくいかなかったのはこういう理由であるから、今度はこうしよう」みたいな。

延々と作っては壊れるのループでしかなく、アイデアの種としてはよくてもそのアイデアが昇華していくことがないわけです。

ここには言った本人と現場との間に大きなギャップがあります。

その人に先見の明があるのであれば、結果として大きなものを生み出すかもしれませんが、こういったことをする人は大抵何かが抜けているように見えます。

サービスがよくても運用が考えられていなかったり、仕組みがよくても展開方法に問題があったり、アイデアがよくても実装に問題があったり。

 

そういったものを見ると現場としては少し考えただけでその仕組みがすぐに破綻することが目に見えてしまったりします。

 

現場が相当がんばり屋さんだったらどうにか軌道に乗せる事はできるかもしれませんが、果たしてそれをうまく回したとしても意味があるのかどうかは疑問で、一番怖いのはその一言によって生まれてしまった業務が現場に根付いてしまい多大な工数を浪費するだけでなく、それによって新しいことへの投資ができなくなってしまうことだったりします。

 

 

無駄振りへの対処

 

 

一つは本当にやりたいのか、本気で言っているのか(アイデアが馬鹿げていても大抵は本気なんでしょうけど)、その本気度をきちんと見極める必要があります。

 

その熱意をまずは感じ取ってみてそれが無駄になるものかどうかを判断必要はあります。

何でもかんでも本気で受け取っていてはこちらの身が持ちませんので。

 

もし、アイデアが未熟であればそれをきちんと昇華するために工夫や新たなアイデアを付け加える必要も出てきます。

 

無駄振りになるかどうかというのは、最終的なゴールがきちんと描けていないところが大きかったりするのですが、言っていることはわからなくは無いってものって結構多くあったりもします。

要は言っている事は正しいんだけど方法論がやっつけすぎて、そしてその実装もやっつけになってすぐに破綻するというものがあって、そのゴールのイメージを描いてやると目的もはっきりして周りも何ためにこのタスクをするのかというのが明確になってきたりします。

手間がかかるわけですが、最終的に何も残らないものをやるよりはきちんと運用され軌道に乗るものを作るほうが誰しもいいでしょう。

 

ここまではある程度本気で取り組まないといけなかった場合ですが、本当にそれが無駄に終わりそうだというのであれば、言い方は悪いですが適当に流してしまうということもありではないでしょうか。

 

無駄なことに時間を割くよりは本来やらないといけないことや前に進めるべきことがあるでしょうから、形だけ見せてその場を収めてしまうこともできるかもしれません。

まぁ、この辺は人によりますのでちょっとした形を見せたら細かく突っ込んでくる人や形だけでは納得しない人もいたりしますので難しいところではありますが、あえて突っ込ませてみて本人の考えを引き出すやり方もあるでしょう。

 

もう一つは、話を自分たちのやるべき方向性にうまく持っていくやり方です。

 

先に書いたように無駄振りの中にあるアイデアの種としては、本来やらなくてはいけない課題や施策が含まれていたりもしますので、それと自分たちがやろうとしている道筋に強引でも結びつけて引き込んでしまうやり方です。

話が大きくなってしまったりもするのですが、言った本人的にも大きなPJとして動いている体を見れば納得度も増してきたりもしますから。

 

あまりにも突飛な仕事の振り方であれば、話を摩り替えてしまえばそのうち忘れられたりもするんですがね。

 

何れにせよ、言った本人の性格などにもよるので対処として難しくはあるのですが、無駄な仕事をするために振り回されるのは誰しもやりたくないことですから、その本人が言ったことをうまくコントロールして有益なものに変える対処というものを考えた方が楽しく仕事ができるのではないでしょうか。