4 Teori

Dapatan aku daripada permainan Kerbal Space Program, aku berpendapat terdapat 3 perkara yang mungkin terjadi kenapa perkara seperti gambar di bawah terjadi. Tetapi merujuk kepada satu perkara yang sama iaitu daya angkat.

  1. Tekanan atmosfera yang rendah
  2. Masalah enjin yang tidak memberikan daya angkat
  3. Masalah aerodinamik
  4. Berat berlebihan

Tekanan atmosfera yang rendah dapat kita abaikan kerana mengikut laporan pihak di sana, cuaca baik.

Masalah enjin mungkin berlaku atas beberapa sebab seperti enjin memang tidak berfungsi dengan baik, enjin tiba-tiba rosak atas beberapa perkara seperti mekanikal mahupun kesan luaran (kemasukkan burung dan sebagainya)

Masalah aerodinamik yang mungkin juga berlaku atas sebab mekanikal (fatigue) mahupun kesan luaran (burung, banggunan). Tetapi kita boleh mengabaikan kesan fatigue kerana pesawat ini amat baru.

Berat berlebihan yang salah perkiraan juga mungkin berlaku tetapi sepatutnya hal tersebut telah lama dimasukkan ke dalam SOP penerbangan dan dengan pesawat yang baru sebegitu aku rasa sudah lebih canggih sistemnya. Kita tolak ketepi, tetapi jangan abaikan.

Nota: Aku tidak meletakkan sebarang kata kunci khas yang merujuk kepada kemalangan tersebut kerana ini hanya pendapat sendiri. Tiada sebarang nombor-nombor yang boleh dikeluarkan sebagai sandaran.

Ganti Redis:: dengan Cache::

Jika anda mempunyai kemampuan untuk pasang ext-redis kepada PHP anda, maka anda tidak perlu menggunakan Redis:: tetapi cukup menggunakan Cache:: sahaja.

Perubahan yang perlu dibuat adalah tukar cache setting didalam .env daripada file kepada redis.

CACHE_DRIVER=redis

Kemudian ubah kod yang sebelum ini adalah panjang:

// app/Http/Repositories/AnnouncementRepository.php

public static function getActiveAnnouncements($date)
{
	$announcements = Redis::get('announcements:active');

	if ($announcements == null) {
		$announcements = Announcement::where('start_at', '<=', $date)
		->where('end_at', '>=', $date)
		->get();

            // make it expired every 6 hours
		Redis::set('announcements:active', $announcements, 43200);
	} else {
		$announcements = json_decode($announcements);
	}

	return $announcements;
}

Kepada yang lebih pendek:

// app/Http/Repositories/AnnouncementRepository.php

public static function getActiveAnnouncements($date)
{
return Cache::remember('announcements:active', 360, function () use ($date) {
return Announcement::where('start_at', '<=', $date)
->where('end_at', '>=', $date)
->get();
});
}

Kebaikkannya adalah dengan menggunakan Redis:: data yang diberikan adalah bentuk json string tetapi menggunakan Cache:: data yang dipulangkan kepada kita adalah di dalam bentuk collection.

Atur Cara

Peka Bahasa DBP

Petang ini akaun Twitter DBP ada mengeluarkan satu lembaran Peka Bahasa yang mana aku tertarik dengan perkataan atur cara. Aku terfikir, mengapa atur cara dijarakkan tetapi pengaturcaraan dirapatkan. Adakah kerana imbuhan peng-...-an tersebut menyebabkan perkataan pengaturcaraan tidak boleh berdiri dengan sendiri dan perlu dirapatkan menjadi satu perkataan. Tetapi jika imbuhan tersebut hanya peng- sahaja dia masih boleh berdiri dengan sendiri sebagai contoh kes ini, pengatur cara.

Dewan Bahasa Edisi Keempat

  • Jadual pelbagai acara (kegiatan dsb) yg telah ditetapkan utk dilaksanakan (biasanya dlm sesuatu upacara, persidangan, persembahan, dll)
  •  (Komp) urutan arahan berkod yg dimasukkan ke dlm komputer yg membolehkan data diproses (oleh komputer); pengaturcaraan (Komp) proses membuat atur cara komputer
  • Pengatur cara 1. orang yg mengendalikan sesuatu majlis; 2. (Komp) orang yg menganalisis sesuatu masalah dan menulis atur cara supaya data yg berkaitan boleh di-proses oleh komputer.

Kes yang sama adalah mudah cara, pemudah cara, pemudahcaraan. Sungguh benar, tatabahasa aku dah karat.

Hapus data, adakah masih perlu?

Semasa aku belajar dahulu untuk setiap sistem secara asasnya mempunyai empat fungsi teras. C.R.U.D.

  • C – Create (cipta)
  • R – Retrive/Read (capai kembali)
  • U – Update (kemaskini)
  • D – Delete (hapus)

Namun, pada zaman kini aku berpendapat sudah sampai masanya untuk kita menukar fungsi yang keempat daripada D iaitu delete atau hapus kepada S – Soft-delete atau hapus secara aplikasi tetapi bukan secara fizikal. Dengan kata lain yang lebih mudah, secara dalam aplikasi pengguna akan menganggap data tersebut dihapuskan kerana tidak dapat dicari melalui paparan sistem. Tetapi secara fizikal di dalam pangkalan data, datanya masih wujud.

is_deleted

Aku mula mempraktikkan kaedah soft delete ini daripada dulu tetapi secara kaedah boolean is_deleted. Data yang disimpan selalunya hanya bersifat 0 atau 1 iaitu 0 – tidak atau false, manakala 1 bermaksud ya atau true.

idNamais_deleted
1Ali1
2Abu0

Dalam contoh table di atas, Ali telah dijadikan sebagai soft delete yang mana datanya dianggap tidak ada di dalam paparan pengguna tetapi secara fizikalnya masih ada dan tidak dihapuskan secara sebenar. Antara kegunaan kaedah ini adalah selain daripada dapat menghilangkan paparan data Ali kepada pengguna sistem, aku juga dapat mengekalkan data yang berkaitan dengan Ali dan juga dapat mengembalikan data Ali jika perlu ke dalam sistem dalam kes-kes tertentu seperti rollback.

Tetapi kaedah ini memerlukan aku menambah setiap query kepada pangkalan data dengan membuat pemeriksaan data ... where is_deleted != 1. Itu semua sebelum datangnya Laravel.

Soft Delete di dalam Laravel

Laravel memperkenalkan kaedah soft delete yang lebih mudah daripada apa aku buat sebelum ini. Aku hanya perlu membuat beberapa perkara dan aku boleh gunakanya:

  1. Tambah deleted_at kepada table sedia ada
  2. Suntik fungsi soft delete ke dalam modul untuk memberitahu Laravel bahawa kita mahu gunakan fungsi soft delete untuk modul tersebut.

Dan selepas itu siap. Anda boleh gunakan terus fungsi soft delete tanpa mengubah apa-apa kod yang sebelum ini. Kaedahnya masih sama seperti contoh:

idnamadeleted_at
1Ali2018-09-23 22:00:00
2Abunull

Maka apabila anda membuat query kepada pangkalan data, Eloquent akan menambah secara automatik satu where untuk mencari data yang mempunyai nilai deleted_at is null sahaja. Dan apabila ditambah dengan kecanggihan Eloquent, anda terus dapat menapis segala data yang berkaitan dengan Ali walaupun berkaitan dengan table yang lain.

Anda masih boleh mengeluarkan data Ali secara paksa dengan menggunakan arahan ->withTrashed() ke dalam Eloquent dan semua data akan dikeluarkan termasuklah yang di hapus menggunakan soft delete.

Intergriti Data

Antara sebab kenapa aku amat memberatkan fungsi soft delete di dalam sistem lebih lagi yang menggunakan Laravel (sebab mudah) adalah kerana bagi aku setiap data yang masuk ke dalam sistem (yang live), sama ada itu adalah data contoh mahupun data spam tidak boleh dibuang. Apatah lagi data yang berkaitan maklumat di dalam server yang sensitif seperti audit trail, log kronologi, evaluation ataupun data transaction yang melibatkan wang. Ini dapat memastikan bahawa sesebuah sistem itu mempunyai intergriti data yang baik.

Ada sesetengah daripada sistem yang aku jaga, tetapan untuk pengguna pangkalan data yang digunakan untuk sistem juga tidak mempunyai fungsi hapus (delete) kecuali kepada beberapa table seperti reset password, token, queue dan seumpamanya yang memerlukan kita membuang data yang telah selesai kerja. Tetapi selain daripada itu memang tiada istilah buang data daripada pangkalan data.

Data banyak tak berat ke?

Data banyak tidak dinafikan akan memberikan impak kepada sistem tetapi kita hidup di zaman big data dan zaman kini mempunyai banyak cara untuk memastikan data yang banyak tidak menyebabkan sistem menjadi terlalu lambat. Contohnya sharding, partitioning, dan archiving. Maka aku tidak nampak kenapa data perlu di buang.

Notakaki

Dah lama nak tulis tetapi selepas JomLaunch 6.0 aku rasa perlu untuk aku tuliskan di dalam blog.

Jambangan Bungamu Tersiksa

Apa yang dimaksudkan “jambangan bungamu tersiksa” dalam lagu Ben Nathan, Tak Mungkin Ku Lepas Pergi?

Dulu pernah ku berkata sayang
Tak mungkin ku menanti lagi
Usiamu pun meningkat jua
Jambangan bungamu tersiksa

Aku dah pernah dengar lagu ini beberapa kali tetapi aku masih tidak dapat mencari maksud yang kena dengan rangkap tersebut. Kenapa jambangan bunga?

Adakah bermaksud seri sebagai seorang perempuan? Jika tentang seri mungkin juga ingin mengatakan semakin tua seseorang perempuan itu, serinya semakin layu? Tetapi kenapa dia tak mahu berkahwin sahaja. Adakah kerana tidak bersedia untuk berkahwin. Kerana kita sedang berkata tentang keadaan zaman dahulu yang mana orang kahwin awal. Bukan seperti sekarang.

Adakah bermaksud kemanisan dalam hubungan? Tetapi jika hanya tentang perhubungan takkan diletakkan rangkap “usiamu pun meningkat jua”. Adakah pula tentang simbol kesuburan? Tetapi kalau hanya tentang kesuburan tak nampak kenapa ayat “tersiksa” digunakan disitu.

Yang aku dapat fikirkan adalah perempuan tersebut pernah curang kepadanya dan kini telah dikecewakan oleh lelaki tersebut dan Ben dalam kisah ini mengambilnya kembali dari keadaan kekecewaan. Ini agak logik kerana terdapat rangkap di bawahnya:

Dulu pernah ku berkata dewi
Tak mungkin ku menunggu lagi
Tapi kini ku sedari hati
Tak mungkin ku lepas kau pergi

Jika diambil dalam sudut pandang ini, seperti ada kesinambungan dengan lagu Jamal Abdillah, Bunga Pujaan (aku lebih minat versi Jamal Abdillah dari Eddy Silitongga). Yang keduanya menceritakan tetang kekasih yang telah pergi meninggalkan mereka dah dikecewakan pula oleh orang lain.

Akan ku biarkan tak sampai dihati
Bunga jadi kupetik akhirnya

Bunga Pujaan, Jamal Abdillah

Jambangan

Perkataan “jambangan” digunakan dan bukannya kuntuman. Selalunya perempuan itu diibaratkan sebagai sekuntum bunga bukannya tempat letak bunga seperti pasu. Adakah sebernarnya lagu ini adalah lagu untuk perempuan kepada lelaki bukannya sebaliknya dengan menjadikan lelaki tersebut adalah tempat letak kuntuman bunga (perempuan)? Mungkin juga tidak kerana jika kita ikut pantun ini;

Sirih puan depan tangga,
Menyambung datang orang marhaban;
Tanya puan dijawab duka,
Bunga di jambangan telah kepunyaan

Kurik Kundi Merah Saga, DBP

atau seperti pantun ini

Pergi ke perigi mengambil timba,
Timba terletak tepi halaman;
Walaupun banyak kembang di rimba,
Mawar di jambangan jadi idaman.

Kurik Kundi Merah Saga, DBP

Daripada pantun ini seolah-olah jambangan tersebut adalah ibu bapanya yang menjaga bunga agar kekal segar dan cantik sebelum dipindahkan kepada jambangan yang lain (suaminya). Jika ini diambil kira, maksudnya ibu bapa kepada perempuan tersebut tersiksa untuk menjawab pertanyaan orang kenapa anak daranya masih belum berkahwin sedangkan usianya meningkat. Itu logik dengan keadaan orang zaman dahulu.

Setakat ini, aku rasa yang terakhir itulah jawapannya.

Rehash Password

Bilakah masa yang kita perlu hash semua (rehash) kata laluan kita?

Setakat ini saya hanya jumpa satu masa sahaja iaitu apabila kita menukar sebarang setting kepada teknik hash sama ada faktor kerja (eg. ulangan) atau kita menukar algoritma atau library hash itu sendiri (eg. Bcrypt kepada Argon)

Pemeriksaan sama ada kata laluan tersebut memerlukan hash semula atau tidak hanya dibuat apabila pengguna membuat log masuk ke dalam sistem dengan menggunakan kata laluan sedia ada. Contoh kes, Ali mempunyai kata laluan “rahsia” untuk log masuk ke dalam sistem. Pada tahun lepas, hash untuk kata laluan Ali tersebut adalah 

$2y$10$3xEVXIUumHCpZU59ZJFoJuOs3lED9ZaNaszlzX71YVETC.tR/W8d.

Menggunakan Bcrypt, dengan faktor kerja ulangan sebanyak 10 ulangan. (rujuk $2y$10 di hadapan hash). Tetapi pada tahun ini, sistem telah menukar algoritma kata laluan kepada Argon dengan faktor kerja memori 1024, bebenang 2, dan masa adalah 2. Ali masih boleh menggunakan kata laluan yang sedia ada dan hash yang sedia ada untuk masuk ke dalam sistem kerana sistem akan tahu bahawa hash yang Ali ada sekarang adalah bersifat Bcrypt bukannya Argon yang baharu.

Selalunya kes ini akan berakhir begitu sahaja sehinggalah Ali menukar kata laluannya. Tetapi kita boleh membuat satu pemeriksaan tambahan selepas Ali berjaya masuk ke dalam sistem dengan memeriksa sama ada hash untuk kata laluannya memerlukan hash semula atau tidak dengan membuat kod seperti ini;

if (Hash::needsRehash($user->password)) {
    $user->password = Hash::make($request->password);
    $user->save();
}

Selepas itu, jika diperlukan untuk membuat hash semula, sistem akan menjana hash yang baru untuk kata laluan Ali dan menyimpannya ke dalam pangkalan data. Hash kata laluan Ali yang baru adalah

$argon2i$v=19$m=1024,t=2,p=2$Y0tPY1dGOXhsR3VZSkozaQ$xYEN90AjVjBqp6j27m2YmtfqrOtG6l6Qk6A0NHIxLxs

Aku sepasang kasut

Aku terjaga dari tidur yang panjang. Di sebalik semak yang gelap dan meninggi, di situ aku masih terbaring keseorangan. Dibiarkan sedang air dari langit merintik air dingin membasahi muka dan badanku. Ah hujan rupanya. Bukan aku pinta untuk lahir ke dunia ini sebagai peti sejuk. Yang apabila elok disukai kerana isi badanku yang sejuk. Tetapi apabila rosak, semak menjadi temanku. Apakan daya, sudah nasibku. Derap-derap bunyi tapak kaki sesekali aku dengar apabila orang berjalan-jalan melintasi laluan di sekitar ku. Alangkah bagusnya jika aku adalah sepasang kasut, menjadi sebelah kasut pun sudah mencukupi. Ah biarkan aku tidur lagi.

Aku terjaga sekali lagi aku terdengar bunyi bising bisik-bisik dari suara yang ramai. Aku tidak pasti dimana. Keadaan gelap gelita. Yang pasti ada bunyi lori dan bau sekeliling adalah seperti bau kulit binatang yang telah di proses. Ku raba sekeliling badanku, aku jadi sedikit aneh kerana tiada badan yang besar dan berat tetapi hanya sekeping sahaja badanku kini. Aku kurang pasti apa yang terjadi selepas itu, yang aku ingat hanya beberapa perkara.

Aku terlihat cahaya terang dan kemudian ada beberapa tangan-tangan manusia mahupun bukan manusia yang aku rasa itulah mereka kata robot. Aku dipotong beberapa kali, kepada beberapa bahagian. Sakitnya bukan kepalang tetapi apabila aku menjerit tiada siapa yang mendengarnya. Kemudian ku dijahitkan semula. Dicantum satu persatu bahagian badanku dan setelah aku sedar apa yang sedang berlaku, aku tahu aku bukan lagi peti sejuk yang dahulu tetapi aku kini ialah sepasang kasut kulit berkilat  berwarna hitam pekat dengan gaya Oxford. Kagum aku dengan diriku yang baru kerana menjadi sepasang kasut yang punya citarasa yang tinggi di dalam fesyen.

Tidak lama aku di kedai, aku mendapat tuan yang baharu. Seorang pekerja eksekutif di sebuah pejabat ternama. Dia memakaiku hampir setiap hari kerana ada masanya dia merehatkan aku kerana katanya adalah untuk menjadikan aku tahan lebih lama. Aku suka. Dia menggilapku hampir setiap minggu. Paling tidak dia akan memberus badanku. Aku membantunya untuk berjalan ke banyak tempat. Dari pagi hingga petang, dari satu kawasan ke satu kawasan yang lain. Dari satu pejabat ke pejabat yang lain.

Tetapi semua itu tak lama, selang beberapa tahun dia mula mengabaikan ku. Kadang-kala aku termasuk ke lopak air, kadang-kala debu dan pasir menhinggapi badanku. Tuan ku ini tidak rajin sangat membersihkan aku. Masa beli dahulu dia memang rajin tetapi kini sudah tidak lagi. Lama kelamaan badanku menjadi capuk dan rosak kerana tidak dijaga dengan betul. Apabila semakin rosak dia cuba membaiki ku tetapi tukang kasut yang ditemuinya mengatakan aku sudah tidak boleh dibaiki lagi kerana rosaknya terlalu banyak dan kosnya terlalu tinggi. Tuan ku mendengus kerana dianggapnya kualiti aku tidak bagus walaupun hargaku mahal. Sedih aku mendengar tohmahan tersebut.

Aku dicampakkan ke tong sampah kerana tidak mampu lagi diperbaiki. Selang beberapa hari, pekerja pengumpul sampah mengambil ku dan mencampakkan pula ku ke perut lori sampah yang besar. Tergolek aku ke dalam timbunan sampah tersebut. Aku nampak pintu lori sampah sudah mula menutup secara perlahan. Selamat tinggal dunia. Selamat tinggal semua. Aku menutup mata sambil air mata ku berjurai ke pipi.

Tiba-tiba aku terjaga. Ah, aku bermimpi. Aku kini menjadi peti sejuk yang ditinggalkan semula. Aku terjaga kerana ada seorang yang sedang menaikkan ku ke atas sebuah lori. Di dalam lori tersebut ada beberapa barang rosak yang lain. Kata mereka, lelaki ini orang yang suka memberikan hidup baru kepada barangan rosak seperti aku dan mereka. Maka aku tersenyum, mungkin ada baiknya aku bukan sepasang kasut.

Nota: Imaginasikan diri anda sebagai sebuah peti sejuk. Tulis karangan tentang “Aku Sepasang kasut”. (25 Markah)

Tips Buat Aduan Di Unifi

Nota: Unifi disini aku khususkan kepada Unifi di rumah. Bukan telefon bimbit.

Tips ini bukan hanya kepada Unifi tetapi kepada semua perkara. Tl;dr; pastikan anda bersedia untuk membuat laporan. Sebelum membuat panggilan ke 100, ataupun melalui Facebook mahupun Twitter, pastikan anda sudah cukup bersedia dengan semua perkara ini:

Self Diagnose

Self diagnose ini adalah paling penting untuk mempercepatkan urusan dua pihak. Pihak anda yang melaporkan dan juga front desk yang menerima laporan. Antara self diagnose yang anda boleh buat adalah:

  1. Ambil kertas dan pen – Catat semua perkara. Kalau boleh ingat semua benda tak pe. Kalau dah tua sila tulis. Jangan belagak.
  2. Tulis apa masalah anda – Tiada internet? Tiada WiFi ? UnifiTV tak keluar? Laman tertentu tak keluar tapi yang lain keluar? Internet perlahan? 
  3. Semua peralatan dihidupkan – Pastikan semua peralatan yang ada dihidupkan. Kalau ada yang pelik seperti lampu warna merah di modem sebagai contoh, catatkan dalam kertas.
  4. Restart peralatan – Jika anda menggunakan Unifi, maka anda akan dibekalkan dengan Modem & Router. Modem berwarna silver kalau tak salah saya dan ada log TM berlampu putih atau merah bila dihidupkan. Router tu selalunya yang warna hitam atau ada tercacak arial di badannya. Ikut turutan. Matikan modem dan router. Biarkan 5 minit, hidupkan modem sahaja dahulu. Biarkan 2 minit. Hidupkan pula router. Kembali kepada nombor #3 kalau ada perubahan yang tak sama selepas itu. Adakah interent anda ok selepas itu? Jika tidak pergi #5
  5. Ulang proses #4. Adakah interent anda ok selepas itu? Jika tidak pergi #6
  6. Ulang proses #4. Adakah interent anda ok selepas itu? Jika tidak pergi #7
  7. Catatkan di dalam kertas, anda telah restart sebanyak 3 kali. Tetapi masih sama. Maka kemungkinan besar masalah bukan daripada perkakasan dalam rumah. Itu adalah satu diagnose penting.
  8. Jika masalah anda adalah WiFi – sila cuba buat speedtest menggunakan http://speedtest.tm.com.my dan catat kelajuan yang anda dapat. Adakah sama dengan apa yang anda langgan daripada TM. 80% margin adalah baik. Jika rendah, cuba balik dengan menggunakan kabel pula dan catat di atas kertas. Adakah masih rendah atau sudah menjadi ok. Jika ok, kemungkinan besar bukan masalah daripada internet Unifi tetapi perkakasan yang salah setting atau WiFi limitation atau interference. Tulis di dalam kertas yang anda perlukan nasihat untuk masalah WiFi.

Telefon 100

Tips paling penting semasa telefon 100 adalah: jangan maki dia.

 Kebanyakkan orang yang jaga helpdesk atau teknikalnya dipanggil 1st level support ni adalah orang yang bukan mahir mana pun tentang teknikal yang terperinci. Tugas mereka hanya merekodkan masalah daripada pengguna dan membantu secara berskrip. Maka, jangan maki, jangan marah, jangan herdik, jangan carut, jangan keluar kata kesat.

  1. Encik dah restart modem? – Ni soalan biasa. Bagi tahu dia yang anda telah restart modem dan router mengikut turutan sebanyak 3 kali ulangan dan masih menghadapi masalah yang sama.
  2. Speedtest – Berikan juga kelajuan internet yang anda catat tadi daripada WiFI dan juga kabel.
  3. Jika ada sebarang tanda pelik seperti lampu warna merah, beri tahu tentang perkara tersebut.
  4. Jika ada sebarang step tambahan yang dia suruh buat, lakukan dan catat perkara tersebut untuk dimasukkan ke dalam checklist self diagnose anda lain kali.
  5. Nombor aduan – Pastikan anda dapat nombor aduan selepas buat aduan. Tidak kira sama ada berjaya selesai atau tidak. Simpan sekali tarikh aduan anda. Kalau dapat nama operator lebih baik. Minta juga mereka grace period selama 3 hari paling kurang sebelum tutup aduan. Dalam masa 3 hari pastikan anda selalu menjalankan speedtest dan periksa Unifi anda. Catat hasil setiap speedtest yang dijalankan.

Masalah berlaku lagi

Jika masalah berlaku lagi kepada Unifi anda selepas kes di tutup, jalankan semula self diagnose anda. Catat semua keputusan diagnose yang baru. Periksa adakah masalah itu sama dengan masalah yang sebelum ini. Jika sama, telefon 100 dan maklumkan bahawa masalah yang sama pernah berlaku dan berikan nombor aduan serta tarikh aduan. Jika masalah yang sama kerap berlaku maka minta untuk mereka hantarkan pasukan teknikal ke tempat anda untuk membantu masalah tersebut.

Tetapi jika masalah itu berlaku sebelum kes ditutup, telefon 100 segera untuk mengelakkan mereka menutup kes tersebut. Berikan nombor aduan yang sebelum ini sebagai rujukan. Jangan lupa self diagnose.

Notakaki

  1. Self diagnose adalah penting. Belajar buat self diagnose. Tidak kira masalah Unifi, masalah kereta, masalah kesihatan, masalah periuk nasi tak masak betul, self diagnose adalah penting.
  2. Nota ini adalah hanya sebagai rujukan untuk membantu anda dan pihak Unifi membetulkan masalah jika ada.
  3. Kalau laporkan melalui Twitter atau Facebook, tak perlu mention Gobind. Tak de guna. Unifi ada SOP dan SLA sendiri.

Dua database berlainan

Apa yang anda boleh lakukan jika untuk semua query yang berjenis read perlu menggunakan pangkalan data A, dan untuk semua query yang berjenis write perlu menggunakan pangkalan data B.

Itu adalah soalan yang mana aku jumpa apabila menggunkan MySQL InnoDB Cluster. Apabila terdapat lebih daripada satu database yang mempunyai data yang sama tetapi fungsi yang berlainan, setiap query perlu menggunakan database yang khusus.

Dalam isu InnoDB Cluster, kami telah memasang MySQL Router di dalam server sebagai pembantu dalam menentukan IP pangkalan data yang mana perlu dibuat query. Apa yang telah dibuat adalah dengan membuat hubungan kepada pangkalan data adalah seperti berikut:

// Write
IP: 127.0.0.1
Port: 6666

// Read
IP: 127.0.0.1
Port: 6667

Mujur, di dalam Laravel, ada kaedah yang mudah untuk anda membuat penetapan supaya masalah ini diselesaikan oleh Laravel secara automatik.

// app/config/database.php

'mysql' => [
	'read' => [
		'host' => env('DB_HOST_READ', '127.0.0.1'),
		'port' => env('DB_PORT_READ', '3306'),
	],
	'write' => [
		'host' => env('DB_HOST_WRITE', '127.0.0.1'),
		'port' => env('DB_PORT_WRITE', '3306'),
	],
	'driver' => 'mysql',
	'database' => env('DB_DATABASE', 'forge'),
	'username' => env('DB_USERNAME', 'forge'),
	'password' => env('DB_PASSWORD', ''),
	'unix_socket' => env('DB_SOCKET', ''),
	'charset' => 'utf8mb4',
	'collation' => 'utf8mb4_unicode_ci',
	'prefix' => '',
	'strict' => true,
	'engine' => null,
],

Saya telah tambahkan parameter read dan write dan menyatakan apakah host dan port yang perlu digunakan mengikut keadaan query yang mahu dibuat.

// .env

DB_CONNECTION=mysql
DB_HOST_READ=127.0.0.1
DB_PORT_READ=6667
DB_HOST_WRITE=127.0.0.1
DB_PORT_WRITE=6666
DB_DATABASE=nama_database
DB_USERNAME=root
DB_PASSWORD=

Ubah fail env ikut kesesuaian.

Asas Redis

Redis adalah salah satu daripada data cache yang bagi aku amat suka lebih lagi jika digandingkan bersama Laravel kerana bagi aku redis dan laravel agak senang nak dibuat.

Pertama sekali adalah, pasang redis pada server anda. Kalau tak ada maka boleh rujuk pada kaedah pemasangan redis yang pelbagai. Kemudian untuk Laravel, pasang pula library predis yang akan membantu Laravel berhubung dengan redis.

composer require predis/predis

Kalau tak ada sebarang perubahan secara manual yang korang jalankan, sepatutnya dah boleh guna terus. Untuk kali ini aku letakkan contoh dimana apabila seorang pengguna masuk ke paparan log masuk sesebuah sistem, dia akan dapat melihat;

  1. Form login page
  2. Pengumuman yang masih aktif

Maka secara normalnya, setiap kali pengguna masuk ke paparan log masuk, sistem akan membuat satu query baru kepada database untuk mendapatkan senarai pengumuman yang masih aktif. Dengan kata lain, jika ada 1000 pengguna masuk ke sesebuah paparan yang sama maka 1000 kali query yang sama akan dijalankan kepada pangkalan data. Dan disebabkan datanya tidak berubah dalam jangka masa tersebut, maka sebenarnya itu adalah satu jenis pembaziran sumber. Kita boleh kurangkan masalah ini dengan menggunakan cache, dalam kes ini kita gunakan Redis.

// app/Http/Controllers/Auth/LoginController.php

public function showLoginForm()
{
	$today = date('Y-m-d');
	$announcements = Announcement::where('start_at', '<=', $today)
	->where('end_at', '>=', $today)
	->get();

	return view('auth.login')->with(['announcements' => $announcements]);
}

Kod di atas adalah kod asal yang kita akan ubah dengan cara:

  1. Periksa cache di dalam Redis adakah data tersebut sudah ada
  2. Jika tiada, kita query ke pangkalan data
  3. Kemudian masukkan ke dalam cache Redis
  4. Hantar data ke paparan
// app/Http/Controllers/Auth/LoginController.php

public function showLoginForm()
{
	$today = date('Y-m-d');
	$announcements = Redis::get('announcements:active');

	if ($announcements == null) {
		$announcements = Announcement::where('start_at', '<=', $today)
		->where('end_at', '>=', $today)
		->get();

            // make it expired every 6 hours
		Redis::set('announcements:active', $announcements, 43200);
	} else {
		$announcements = json_decode($announcements);
	}

	return view('auth.login')->with(['announcements' => $announcements]);
}

Maka jika kita lihat dengan menggunakan library seperti Laravel Debugbar, kita akan dapat dapati tiada query baru yang dibuat selepas query pertama dilakukan. Kerana selepas query pertama, query kedua hanya mengambil data yang disimpan secara cache daripada Redis sahaja. Dengan kata lain, jika terdapat 1000 request, kita hanya membuat 1 query sahaja. Penjimatan sebanyak 999 query.

Refactor

Kod di atas tiada masalah, cuma kita boleh cantikkannya lagi dengan mengeluarkan kod yang mencari data pengumuman tersebut dan menukarkannya menjadi fungsi yang khusus untuknya. Perkara ini adalah untuk memudahkan kita menggunakan fungsi yang sama jika perlu sebagai contoh untuk memparkan senarai pengumuman yang sama di dashboard selepas log masuk berjaya.

// app/Http/Repositories/AnnouncementRepository.php

public static function getActiveAnnouncements($date)
{
	$announcements = Redis::get('announcements:active');

	if ($announcements == null) {
		$announcements = Announcement::where('start_at', '<=', $date)
		->where('end_at', '>=', $date)
		->get();

            // make it expired every 6 hours
		Redis::set('announcements:active', $announcements, 43200);
	} else {
		$announcements = json_decode($announcements);
	}

	return $announcements;
}

Saya cipta satu fail baru sebagai repository yang dinamakan sebagai AnnouncementRepository.

// app/Http/Controllers/Auth/LoginController.php

public function showLoginForm()
    {
        $announcements = AnnouncementRepository::getActiveAnnouncements(date('Y-m-d'));

        return view('auth.login')->with(['announcements' => $announcements]);
    }

Kini saya hanya perlu memanggil data pengumuman dengan memanggil fungsi getActiveAnnouncements daripada AnnouncementRepository yang telah dibuat. Sekarang fungsi showLoginForm akan lebih ringkas dan fokus kepada perkara yang mahu dilakukan sahaja.

Notakaki

  • Redis + Laravel = mudah
  • Data di dalam Redis berada di dalam memori. Maka RAM perlu sesuai dengan jumlah data yang disimpan.
  • Redis bukan tempat simpan data yang kekal. Hanya sementara.