---
# System prepended metadata

title: '今週何知った？ week:13'

---

# 今週何知った？ week:13

[![hackmd-github-sync-badge](https://hackmd.io/CFlTER5rRHy37AW44sisZw/badge)](https://hackmd.io/CFlTER5rRHy37AW44sisZw)

> [name=makicamel]

## Observer パターン
Observer パターンとは、プログラム内のオブジェクトに関するイベント（事象）を他のオブジェクトへ通知する処理で使われるデザインパターンの一種  
[Observer パターン - Wikipedia](https://ja.wikipedia.org/wiki/Observer_パターン)

![](https://i.imgur.com/cG9ut0S.png)
- Observer: イベントを通知される。Listener と呼ばれることもある
- Subject: イベントを通知する

### EventEmitter

- EventEmitter とは  
Node.js のコアライブラリで、イベント駆動・オブザーバパターンのパラダイムでのプログラミングをサポートするライブラリ。継承または移譲して用いる  
https://nodejs.org/api/events.html

- バージョン  
11 まであるが 3 が一番ダウンロード数が多い。4 以降はネタ枠っぽい
  - https://www.npmjs.com/package/eventemitter
  - https://www.npmjs.com/package/eventemitter2
  - https://www.npmjs.com/package/eventemitter3

- e.g. http モジュール  
https://github.com/nodejs/node/blob/v17.9.0/lib/_http_server.js#L369
    
`on` でイベントを登録し、 `emit` でイベントを発行して使う


<details><summary>Observer パターンで FizzBuzz</summary>
    
```javascript
function createFizzBuzzEventEmitter(until) { 
  const eventEmitter = new events.EventEmitter()
  process.nextTick(() => _emitFizzBuzz(eventEmitter, until))
  return eventEmitter
}

async function _emitFizzBuzz(eventEmitter, until) {
  eventEmitter.emit('start')
  let count = 1
  while (count <= until) {
    await new Promise(resolve => setTimeout(resolve, 100))
    if (count % 15 === 0) {
      eventEmitter.emit('FizzBuzz', count)
    } else if (count % 3 === 0) {
      eventEmitter.emit('Fizz', count)
    } else if (count % 5 === 0) {
      eventEmitter.emit('Buzz', count)
    }
    count += 1
  }
  eventEmitter.emit('end')
}

function startListener() {
  console.log('start')
}
function fizzListener(count) {
  console.log('Fizz', count)
}
function buzzListener(count) {
  console.log('Buzz', count)
}
function fizzBuzzListener(count) {
  console.log('FizzBuzz', count)
}
function endListener() {
  console.log('end')
  this // this is eventEmitter's instance
    .off('start', startListener)
    .off('Fizz', fizzListener)
    .off('Buzz', buzzListener)
    .off('FizzBuzz', fizzBuzzListener)
    .off('end', endListener)
}

createFizzBuzzEventEmitter(40)
  .on('start', startListener)
  .on('Fizz', fizzListener)
  .on('Buzz', buzzListener)
  .on('FizzBuzz', fizzBuzzListener)
  .on('end', endListener)
```
    
</details>

### EventEmitter とメモリリーク
Node.js はガベージコレクションの機能を備えているため使われなくなった変数は自動的にメモリから削除される。  
EventEmitter インスタンスにリスナを登録した場合はリスナの参照が残る。メモリリークの原因になるため使い終わったらリスナを削除する必要がある。

```javascript
function endListener() {
  console.log('end')
  this // this is eventEmitter's instance
    .off('start', startListener)
    .off('Fizz', fizzListener)
    .off('Buzz', buzzListener)
    .off('FizzBuzz', fizzBuzzListener)
    .off('end', endListener)
}
```
    
> [name=ken3ypa]

# `my.cnf` について
## 動機
- ずっとポスグレばっかりだったが、最近MySQLを触るようになった（ポスグレがわかるとはいってない）
- 設定まわりで雰囲気で書いたりハマることがあったので調べてみた

## 概要
MySQLのコンフィグファイル。マイコンフ・マイテンコンフ。

## 基本的な書き方

- パラメータ名 = 値の形で記述
- スペース・タブはあってもなくてもよい
- ハイフン、アンダースコアは同一視される

```
max_connection=1000
max-connection    =    1000
```

## オプショングループ

my.cnf は複数のプログラムが値を読み出すため、識別子が必要。識別子から各プログラムが読み込む値を判断し適用する

```
[client]
port=3306
socket=/tmp/mysql.sock

[mysqld]
port=3306
socket=/tmp/mysql.sock
key_buffer_size=16M
max_allowed_packet=8M

[mysqldump]
quick

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
```

|グループ|説明|
| --- | --- |
|client|mysqlクライアントツールへの設定|
|mysqld|mysqlサーバーへの設定|
| mysqldump |バックアップコマンドへの設定  |
|mysqld_safe  | 起動ファイル設定 |

#### デフォルト状態のmy.cnf

```
bash-4.4# cat /etc/my.cnf
# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/8.0/en/server-configuration-defaults.html

[mysqld]
#
# Remove leading # and set to the amount of RAM for the most important data
# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
# innodb_buffer_pool_size = 128M
#
# Remove leading # to turn on a very important data integrity option: logging
# changes to the binary log between backups.
# log_bin
#
# Remove leading # to set options mainly useful for reporting servers.
# The server defaults are faster for transactions and fast SELECTs.
# Adjust sizes as needed, experiment to find the optimal values.
# join_buffer_size = 128M
# sort_buffer_size = 2M
# read_rnd_buffer_size = 2M

# Remove leading # to revert to previous value for default_authentication_plugin,
# this will increase compatibility with older clients. For background, see:
# https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_default_authentication_plugin
# default-authentication-plugin=mysql_native_password
skip-host-cache
skip-name-resolve
datadir=/var/lib/mysql
socket=/var/run/mysqld/mysqld.sock
secure-file-priv=/var/lib/mysql-files
user=mysql

pid-file=/var/run/mysqld/mysqld.pid
[client]
socket=/var/run/mysqld/mysqld.sock

!includedir /etc/mysql/conf.d/
```

### 読み込み順
- MySQL関連プログラムは下記の順で自動的に my.cnf を連鎖的に読み込む。その際、最後に読み込んだパラメータを有効にするため読み込み順位が低い方が優先順位が高くなる。

|読み込み順位|ファイル|
| --- | --- |
| 1 | /etc/my.cnf |
| 2 | /etc/mysql/my.cnf |
| 3 | SYSCONFDIR/my.cnf |
| 4 | $MYSQL_HOME/my.cnf |
| 5 | --defaults-extra-file |
| 6 | $HOME/ .my.cnf |
| 7 | $HOME/ .mylogin.cnf |
| 8 | DATADIR/mysqld-auto.cnf |
| 9 | コマンドラインオプションの引数 |


Linux環境だと下記コマンドで各 `my.cnf` の場所と順序を確認可能
```
> mysql --help | grep my.cnf
                      order of preference, my.cnf, $MYSQL_TCP_PORT,
/etc/my.cnf /etc/mysql/my.cnf /usr/etc/my.cnf ~/.my.cnf
```

### 自動読み込みをオフにしたい場合

`mysql --defaults-file=~/.hoge.my.cnf` のようにコマンドラインで読み込ませたい my.cnf を指定すれば、自動読み込みはされず指定したpathのmy.cnfのみが適用される