新着記事

Viewing posts from August, 2018

仕事をする上でいつも思っている言葉

弊社TORICO にインターンとして大木さんというエンジニアが参加されています。ブログをお任せしたところ、職場や働き方についても書かれていました。今回はそれに刺激を受け、私も職に対しての考えを書こうと考えました。今回は、私が仕事をする上でいつも思っている言葉、そして私を変えた言葉をいくつか紹介したいと思います。

TORICOインターンブログ

時間とは、可能性だ

Time is ナントカ。パターンは多くあると思うのですが、私は「可能性」だと思っています。Time is possibility. 自分で思いついた言葉ですが、世界中で同じことを考えている方は多くいるんじゃないかと思っています。

人、特に日本で生まれた人は、手厚い人権に守られているため自由に学校や仕事を選ぶことができます。「何にでもなれる」と言っても大げさではないでしょう。ただし、何にでもなれる可能性は時間が経つごとに減っていきます。ポジションには限りがあり、競争があるためです。

人が時間を使うということは、何かを達成する可能性を取捨選択するということです。時間には、すべての人に平等な限界があります。それを何に使うかで、やりたいことをできる可能性は変わってきます。

日本で生まれて、やりたいことを選ぶ自由がある以上、好きなことをやればいいと本当に思います。そして、何かを選択すれば、それは何かができる可能性として自分の中に蓄積していきます。逆に選ばなかった可能性は捨てることになり、永遠に失われます。時間は巻き戻せないためです。時間は、自分のやりたいことを実現する可能性を高めるために使うものである、と私は考えます。

文句を言う前に頭を使え

これも私が思いついた言葉ですが、いつも忘れずに行動しています。ちなみに言葉で人に伝えたことはありません。パワハラだと言われそうなので。

何か複雑な問題があった時、それが原因でストレスを負った時、文句・愚痴を言ったり言い訳をしたくなることがあります。その言い訳の先にあるのは自分のストレスの解消や虚栄心の確保です。聞かされる人にとってはただただ時間の無駄で、人によってはそれがストレスの原因になりえます。家に帰ったら人形にでも向かって心が穏やかになるまで愚痴を言うのがいいでしょう。

求められることは、課題を効果的に解決できるまで知恵を絞り続けることです。場合によっては「解決できない理由を説明する」だったり「課題を凍結する(先送りにする)」選択もありえると思いますが、文句を言うことはゴールに近づくことにはならず、ただの時間の無駄です。社会人であれば、頭を使って問題に立ち向かいましょう。

人のえらさは平等

社会人になってすぐ、先輩から教わったことです。えらさ、はいろんな意味にとれる言葉ですが、ここでは「人より権利が優れている」という意味で、王国でいう王様のようなえらさです。

日本人である限り、他の日本人よりえらいということは決してありません。すべての人が法のもと平等であると憲法で定められています。

では、会社などの組織に所属した時のヒエラルキーは何なのかというと、ただの雇用契約上の役割や権限の違いでしかありません。アルバイトでも社長でもお客様でも、総理大臣でも、お互いに成人であればえらさの違いはなく、雇用契約であったり売買契約であったり、契約上の権限や役割の違いがあるだけです。組織内での権限の違いを組織内での「えらさ」と表現するのもわからなくはありませんが、「えらさ」という言葉にすると人権的に差があるようにも感じられるかもしれないため、私は言わないようにしています。

会社組織でいうなら、上司は部下に対して人権に優位性があるわけではなく、「評価して賃金を決めることができる権利を組織内で与えられている」程度の違いしかありません。(持ってる株式数に大きな違いが無い場合)。なので、同じ社会人でありプロフェッショナル同士である同僚・部下とは礼儀を持って接するのが大切なことです。彼らが隣の席にいるのは、「自分と同じ会社と雇用契約を結んだ」ただそれだけの理由です。

これからどうするか

これは、アドラー心理学の解説書「幸せになる勇気」から学んだ言葉です。

この本は、カウンセリングをする時、多くは「悪いあいつ」の批判や、「かわいそうなわたし」を訴えるだけで終わってしまう。それは本質の解決にはつながらず、聞き流すだけの内容だと、伝えます。

たしかに愚痴や悪口にはなんの意味も価値もありません。家に帰ったら人形にでも向かって言ってればいいでしょう。大事な話題は「これからどうするか」であり、人と会話をする上で見失ってはいけません。

嫌われる勇気幸せになる勇気

両方人気のある本ですが、内容は面白く、私の行動を形作る要因となっています。おすすめします。

そのほか、この場を使って読んで良かった思う良本を紹介しておきます。

あなたの知らない脳

哲学的な何か、あと科学とか

「これは自分の仕事ではない」と言わない

何かの本か記事で読んだのですが、出展を覚えていません。おそらく Amazon とか AWS の組織について書かれた本だったと思うのですが…。

「これは自分の仕事ではない」と言う前にすべきことは、知恵と勇気をふりしぼって、そしてなりふりかまわず課題の解決に向き合うことです。

知恵をうまく使うことで、具体的には既存のツールや手順をうまく組み合わせることで課題の解決は大きく効率化させることができます。

逆に知恵の範囲が狭ければ、人海戦術と根気での解決策しか考えつかないかもしれません。もしその時、「面倒だ」「もっと効率的にできる方法がありそうだ」と感じれば、効率化する方法は間違いなくあります。知恵と勇気をふりしぼって、対応することで、個人や組織の成長につながるでしょう。

ダメじゃなければOK

私の考えた言葉です。デザインワークをする際は、これを思いながら作業をします。

私は自分で行ったデザインを見直す際、ダメな箇所があるかどうかを注意して確認します。良くできた箇所はまったく気にしません。無視します。ダメな所だけを探します。

ダメな箇所に気づいたら、無くなるまで直します。「○○さんに見せたらここ何か言われるかなー」と感じたら、それはダメな箇所であり、直す必要があります。先鋭的な表現とかメッセージ性とかはあってもなくてもどっちでもいいです。ただし、そもそものコンセプトとして「なければダメ」なら無きゃダメです。ダメな所がみつからなければ、そのデザインはひとまずは「OK」です。

納期までにでっちあげる

マンガ「げんしけん」で、コミケの出版物の納期がせまっておりもう無理だと半ばあきらめかけているチームに向かって登場人物が言った言葉です。

この「でっちあげる」という表現が好きで、納期を最優先とし、あきらめずに手段を選ばず達成する意志を感じます。

本来であれば、クオリティを十分に保って、かつ納期(約束)を守るのが一番良いのですが、両立が難しい場合でもあきらめずに、何としてでも約束は守らなければならないと、この作品は伝えています。

げんしけん、新装版出てた

しっかり練習してこい

スーパーストリートファイター4で、ケンが勝利時にいう言葉。つまり、ケンに負けた時に言われる言葉。その言葉はビデオゲームの範囲を超えて、プレイヤーにも向けられているようです。

ビデオゲームに限らず、どんなゲーム(スポーツ)であれ、勝利するために挑戦するわけですが、勝つ可能性を上げるためには練習と研究が重要です。あとは事前準備とか体調管理とかでしょうか。当たり前のことなのですが、たまに忘れかけてしまうこともあります。

例えば、たまたま1ゲームだけうまくいった時、次も同じようにやればうまくいくと思ってしまうことがありますが、そんなことはありません。それは自己評価が高すぎます。勝ったのはたまたまであり、慢心すると足元を掬われるということを「勝って兜の緒を締めよ」ということわざが思い出させてくれます。

「勝った理由は運が良かったから、負けた理由は実力不足」という言葉もあります。もし、勝ちたくてやることであれば、「しっかり練習してこい」と言われないよう練習しましょう。時間を練習に使えば、勝つ可能性を上げることができます。

逆に、練習に時間を使えないのであれば、そのゲームでは勝つことをあきらめているということになります。

Django に Celery タスクキューを導入し、遅い処理を利用者に体感させないようにする

Django でウェブアプリを作る際、遅い処理をタスクキューにするには、celery が便利です。今回、社内勉強会で Django + celery のチュートリアルを行ったので、celery で簡単なタスクを動かすまでを書いておきます。

内容としては Celery ドキュメントの First steps with Django をなぞっています。

環境

  • MacOS
  • Python 3.6.5
  • Django 2.1
  • Celery 4.2.1
  • Redis

Redisは、キューのブローカーとして使います。Redis以外にも、RabbitMQ やAmazon SQS が使えます。

Redis サーバの起動方法は書いていませんので、適宜起動してください。

プロジェクトフォルダの作成

$ mkdir celery_handson
$ cd celery_handson

venv (仮想環境) の作成

$ python3.6 -m venv venv
$ . venv/bin/activate

ライブラリのインストール

$ pip install django
$ pip install celery django-celery-results redis django-redis
$ pip install ipython

django-admin.py を認識させるため、仮想環境に入り直しておきます。

$ deactivate
$ . venv/bin/activate

Djangoプロジェクトの作成

(今、celery_handson ディレクトリにいますが、さらにその中に celery_handson という名前の Django プロジェクトを作ります)

$ django-admin.py startproject celery_handson
$ cd celery_handson

Django_celery_results の導入

settings.py を編集し、INSTALLED_APPS に django_celery_results を追加します。

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django_celery_results', # ←追加
]

DBの作成

$ ./manage.py migrate

これで、Djangoの初期設定は完了しました。

試しに、

$ ./manage.py runserver

を起動し、http://127.0.0.1:8000/ にアクセスしてみると、テストページが表示されます。

Celery 設定の追加

settings.py に追加します。

CELERY_BROKER_URL = "redis://<Redisサーバのホスト>:6379/1"
CELERY_RESULT_BACKEND = "django-db"

Celery ファイルの作成

celery_handson/celery.py を作成

urls.py の並びに、celery.py を作ります。

# celery_handson/celery_handson/celery.py
import os
from celery import Celery

# set the default Django settings module for the 'celery' program.
settings = os.getenv(
"DJANGO_SETTINGS_MODULE", "celery_handson.settings")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", settings)

app = Celery('celery_handson')

# Using a string here means the worker doesn't have to serialize
# the configuration object to child processes.
# - namespace='CELERY' means all celery-related configuration keys
# should have a `CELERY_` prefix.
app.config_from_object('django.conf:settings', namespace='CELERY')

# Load task modules from all registered Django app configs.
app.autodiscover_tasks(['celery_handson'])

公式ドキュメントにあるファイルほぼそのままです。

タスクスクリプトの作成

urls.py, celery.py の並びに、tasks ディレクトリを作り、その中に __init__.py を作ります。

# celery_handson/celery_handson/tasks/__init__.py
from ..celery import app


@app.task()
def add_numbers(a, b):
print('Request: {}'.format(a + b))
return a + b

celery ワーカーの起動

./manage.py があるディレクトリで行います。

celery -A celery_handson worker --concurrency=1

--concurrency は並列性のオプションで、省略しても問題ありませんが開発中は1が扱いやすいように思います。

ターミナル内で実行し続けますので、そのターミナルはそのままにして、次の「タスクの実行」からは新しいターミナルを起動してください。

(ちなみに celery 実行バイナリは、venv/bin/celery にいます。)

(iTerm2 を使っている場合、ターミナルに画像が表示されます)

タスクの実行

同期処理

$ ./manage.py shell
>>> from celery_handson.tasks import add_numbers
>>> add_numbers(3, 4)
Request: 7
7

普通に同プロセス内で add_numbers をコールしただけです。これは celery は関係ありません。

非同期処理

>>> add_numbers.delay(5, 6)
<AsyncResult: deeddee2-74a6-48ec-9f22-987417135592>

@app.task() デコレータがついた関数は Celery のタスクとして登録され、.delay メソッドが使えるようになっています。.delay をコールすることで、非同期実行のタスクキューとしてブローカーに登録され、ワーカーはそれを拾って処理を行います。

.delay メソッドの戻り値である AsyncResult は、result プロパティの中に結果が入っているかもしれません。

また、django_celery_results を使っていれば処理結果は DB (モデル) に記録され、task_id の値を元に取得することができます。

>>> tr = TaskResult.objects.get(task_id='2781413b-282e-4de8-b134-b338b592ad02')
>>> tr.status
'SUCCESS'
>>> tr.result
'11'

ビュー内で行う重い処理や、マネジメントコマンドから実行するタスクで並列したいものは、このタスクの delay メソッドを使うことで簡単に非同期化でき、使用者のストレスを下げることができます。

PyCharm の設定

タスクの開発は、他のスクリプトと同様にIDEでブレイクポイントを設定すると効率的に開発できます。

Django の環境設定

一番上の celery_handson ディレクトリを PyCharm で開きます。

Project Interpreter

⌘+, で設定を開き、検索窓に interpreter と入力。

Project Interpreter を、先程作った venv 内のPython を指定します。最近の PyCharm は自動認識します。

Django Support

検索窓に django と入力し、Languages & Frameworks ➝ Django の設定をします。Enable Django Support にチェックを入れ、Settings に celery_handson/settings.py を指定。

Project Structure

検索窓に structure と入力し、./manage.py が入っている celery_handson ディレクトリを Sources に追加しておきます。

Run/Debug Configurations の登録

エディタ右上の、Edit Configurations... を選択し、+ ボタンから Django Server を選択 して設定を登録します。

Enironment variables (環境変数) に、DJANGO_SETTINGS_MODULE celery_handson.settings を登録しておきます。(無くても動くかもしれません。PyCharm の他の設定によります。設定しとくと無難です)

この設定を実行すると、Django テストサーバが起動します。

Celery用の設定

Run/Debug Configurations の + をクリック ➝ Python で、

Script path に venv/bin/celery、parameters に -A celery_handson worker --concurrency=1 を、念の為 Environment variables: に DJANGO_SETTINGS_MODULE celery_handson.settings を登録しておきます。

この環境をデバッグ起動すれば、ワーカープロセス内でブレイクポイントが使えるようになり、開発がしやすくなります。

Celery ワーカーの状態取得

from celery.task import control
inspect = control.inspect()
inspect.stats()  # ステータスを取得
inspect.ping()  # 疎通確認
inspect.active()  # 現在実行中のタスク

Supervisor の設定サンプル

[program:celery-handson]
autostart = true
autorestart = true
user = ubuntu
environment = DJANGO_SETTINGS_MODULE=celery_handson.settings
command = /var/django/celery_handson/venv/bin/celery -A celery_handson worker --concurrency=8
directory = /var/django/celery_handson/celery_handson
stopasgroup = true

; logs
stdout_logfile = /var/log/supervisor/celery_handson.log
stdout_logfile_maxbytes = 1MB
stdout_logfile_backups = 5
stdout_capture_maxbytes = 1MB
redirect_stderr = true


; プロセス再起動:
; sudo supervisorctl restart celery-handson


メモ: django_celery_beat でDBで設定したタスクを実行させるには

command = /var/django/celery_handson/venv/bin/celery -A celery_handson beat --scheduler=django_celery_beat.schedulers:DatabaseScheduler
Search