lucaong

lucaong

Best way to restrict file access to one single Elixir/Erlang process

Hi all,
suppose you have an Elixir process that internally accesses a file. For clarity, let’s say that it’s started like this:

{:ok, pid} = MyGenServer.start_link("path/to/file.xyz")

You want to make sure that only that process can access the file. In other words, you want to prevent the user to create more processes accessing the same file:

{:ok, pid} = MyGenServer.start_link("path/to/file.xyz")

MyGenServer.start_link("path/to/file.xyz") # this should return :error, as the file is already used
MyGenServer.start_link("path/to/another_file.xyz") # this is ok, the file is a different one

Ideally, this should work no matter if the two processes are started as part of the same VM, or in different ones. Something similar to file locking, but working for Erlang/Elixir processes rather than OS processes.

I can think of some ways to achieve this, but they all look a bit cumbersome, and maybe there is a simple solution to this that I am missing.

Marked As Solved

lucaong

lucaong

So the solution will be to use either :global.set_lock or a global named process to ensure exclusive access within the same VM instance or cluster. On top of it, use OS-level file locking to restrict access across VM instances on the same machine (not clustered), for example on different IEx sessions.

I will mark this as the solution, but if someone has a better one please point that out :slight_smile:

Also Liked

OvermindDL1

OvermindDL1

This definitely won’t be an Elixir/BEAM question, more of how would you do this via the OS, because that’s the only way to reliably do it. Maybe see how sqlite does it. (Probably a lock file or so I’d guess)

lucaong

lucaong

Hi @pdgonzalez872, thanks for the interesting article :slight_smile:

The problem with named global processes, similarly to global locks, is that they would not prevent me from accessing the same file from two processes if, for example, I open two iex sessions and create a process accessing the file in each of the sessions (without linking the sessions in a cluster).

I know this is not a typical problem in Erlang/Elixir, and I am not asking in order to structure an application. I need this to implement a feature enhancement for a library (therefore @sd4code comment is correct, but not relevant to my case).

If you want to know the actual use-case, my goal is to show a helpful error to users of CubDB if they happen to mistakenly create two DB processes on the same data directory. I want to do something similar to what SQLite does to prevent users to mistakenly start two SQLite processes writing on the same data file, but I need to do that with Elixir/Erlang processes instead of OS processes (as CubDB is native Elixir). CubDB allows concurrent operations on the database, but a single genserver should be responsible of managing file access.

My default solution (which in the end would work reasonably well) is to use a mix of :global.set_lock (to prevent two processes in the same VM writing on the same file) and a “traditional” file lock (to prevent processes in different VMs to write to the same file). I think this is reasonable, but I wanted to check if someone has a better idea in mind.

pdgonzalez872

pdgonzalez872

@lucaong glad you found it interesting, hope you liked my design skills as well :slight_smile:

without linking sessions in a cluster

Very interesting!

Wow, awesome use case. Sorry my suggestion didn’t help, I’m eager to see what others propose here. Hope we see some interesting solutions :slight_smile:

lucaong

lucaong

Yes, SQLite uses file locking. I would use both a file lock and a Erlang global name or lock, to restrict access both within and across Erlang VMs.

Thanks everybody! It looks like I was more or less on the right track. I just wanted to make sure that I was not missing some simple solution.

Where Next?

Popular in Questions Top

Tee
can someone please explain to me how Enum.reduce works with maps
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
mathew4509
I have a list say x = ["23gh", "56kh", "97mh"] I would like to pass each element to Val in each iteration. Say, in iteration 1 -------...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
LegitStack
I’m trying to make a websocket server in Phoenix or raw Elixir. I heard about gun, I think I could use cowboy, but since I’m not that sma...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New

Other popular topics Top

JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: https://hexdocs.pm/ecto/Ecto.Schema.html#module-...
New
_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
chensan
I have a User schema with a :from_id field set to type :string: defmodule TweetBot.Repo.Migrations.CreateUsers do use Ecto.Migration ...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? https://hexdocs.pm/ecto/Ecto.Repo.h...
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
AstonJ
by Lance Halvorsen Elixir and Phoenix are generating tremendous excitement as an unbeatable platform for building modern web application...
460 27162 124
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New

We're in Beta

About us Mission Statement