CLICK HERE TO READ THE ENGLISH VERSION

Implementasi Shared Mutex ke Beberapa Aplikasi ASP .NET

Juldhais Hengkyawan
3 min readMar 17, 2024

Beberapa waktu yang lalu saya mendapat tugas untuk memperbaiki privacy issue yang terjadi pada proses konversi legacy document ke PDF.

Masalahnya cukup serius, yaitu ketika beberapa pengguna mengakses conversion service secara bersamaan, kadang-kadang file mereka tertukar satu sama lain.

Misalnya Tom dan Jerry sedang men-download file secara bersamaan. Tom malah mendapat file milik Jerry dan Jerry mendapat file milik Tom.

Masalah ini terjadi karena ada dua aplikasi ASP .NET yang berjalan di satu VM yang sama, dan keduanya mengakses satu aplikasi converter yang sama.

Pihak management menginginkan solusi yang cepat untuk masalah serius ini.

Setelah berpikir beberapa saat, saya memutuskan bahwa Mutex adalah solusi yang cepat dan efisien untuk menyelesaikan masalah ini.

Idenya sederhana: pastikan bahwa proses konversi dokumen hanya dapat diakses oleh satu aplikasi pada saat yang sama.

Cara ini akan menyelesaikan masalah file yang tertukar dan memastikan data pengguna tetap aman.

Apa itu Mutex?

Mutex adalah mekanisme sinkronisasi yang memastikan hanya ada satu thread atau proses yang dapat menjalankan bagian code tertentu.

Tetapi, karena ada dua aplikasi ASP .NET yang mengakses satu resource yang sama, ada konfigurasi yang harus dilakukan agar Mutex dapat diakses oleh kedua aplikasi tersebut.

Ada dua hal yang harus dikonfigurasi: Mutex access rule dan Mutex name. Hal ini akan memungkinan satu Mutex tersebut dapat diakses oleh kedua aplikasi yang berbeda.

Mutex Access Rule

Kuncinya di sini adalah penggunaan WellKnownSidType.BuiltinUsersSid. Hal ini memungkinan Mutex dapat diakses oleh kedua aplikasi, karena kedua aplikasi tersebut dijalankan oleh IIS user yang sama.

var accessRule = new MutexAccessRule(
new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null),
MutexRights.FullControl,
AccessControlType.Allow);

var securitySettings = new MutexSecurity();
securitySettings.AddAccessRule(accessRule);

Kita juga dapat memperluas scope dari access rule dengan menggunakan WellKnownSidType.WorldSid. Tetapi kita perlu berhati-hati karena Mutex menjadi dapat diakses oleh semua aplikasi dan user yang ada di VM tersebut.

Nama Mutex

Agar Mutex dapat diakses oleh banyak aplikasi, kita juga harus memberi nama pada Mutex tersebut.

using (var mutex = new Mutex(false, "Global\\PdfConversion", out _, securitySettings))
{
// ...
}

Nama Mutex harus sama untuk setiap aplikasi, dan juga harus diawali dengan prefix “Global\” agar Mutex menjadi visible untuk siapa saja di dalam VM tersebut.

Implementasi Mutex

Setelah mengkonfigurasi access rule dan name, sekarang kita dapat mengimplementasikan code yang akan “dibungkus” oleh Mutex tersebut:

var accessRule = new MutexAccessRule(
new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null),
MutexRights.FullControl,
AccessControlType.Allow);

var securitySettings = new MutexSecurity();
securitySettings.AddAccessRule(accessRule);

using (var mutex = new Mutex(false, "Global\\PdfConversion", out _, securitySettings))
{
try
{
// Attempt to acquire the mutex
// Waiting up to 2 minutes for availability
mutex.WaitOne(120000);

// If acquired, run the document conversion process
return RunConversion(doc);
}
catch (AbandonedMutexException)
{
// If the mutex was abandoned, release it and try to acquire it again
mutex.ReleaseMutex();

// Wait again up to 2 minutes for the mutex
mutex.WaitOne(120000);

// Once acquired, re-run the document conversion process
return RunConversion(doc);
}
finally
{
// Always release the mutex when done to allow other processes to use the resource
mutex.ReleaseMutex();
}
}

Testing

Testing dilakukan dengan menggunakan PowerShell command untuk melakukan simultaneous access:

Start-Job {Invoke-WebRequest -Uri https://localhost:1000/api/download/1 -OutFile C:\file1.pdf}
Start-Job {Invoke-WebRequest -Uri https://localhost:1000/api/download/2 -OutFile C:\file2.pdf}
Start-Job {Invoke-WebRequest -Uri https://localhost:2000/api/download/3 -OutFile C:\file3.pdf}
Start-Job {Invoke-WebRequest -Uri https://localhost:2000/api/download/4 -OutFile C:\file4.pdf}
...etc

Setelah melakukan testing dan regression, hotfix akhirnya di-deploy ke production. Masalah privacy issue yang kompleks dapat diselesaikan dengan solusi yang relatif sederhana.

Terima kasih telah membaca, semoga bermanfaat 👍

--

--