5HT/fs

Consider support fswatch

josevalim opened this issue · 23 comments

fswatch supports unix, freebsd and mac, so it looks like a nice alternative. I am posting it here in case someone wants to tackle it: https://github.com/emcrisostomo/fswatch

5HT commented

I will take a look closely after finishing my trip.
While it longs, I'm just saying Hello from Tibet :-)

FreeBSD user here .. I would really like to have this, too :)

Cheers

5HT commented

Oh hai!
I see https://github.com/Vagabond/erl_kqueue
Or there is better/smaller filesystem watching API ?

UPD. I added basic freebsd compilation and bsd running support but it should be finished.

5HT commented

@josevalim I reviewed fswatch. I'd better support everything that users of elixir and erlang is using. I just don't want to throw away our backends. They are cute. From the other side fs won't rely on anything, we have freedom.

kuon commented

I started developing on freebsd as well (phoenix) and no support for code reloading is a bit problematic. Any ETA on this fix? I can provide help with testing if needed.

Found the following error in FreeBSD 11.0-BETA2 with Erlang/OTP 19.0.2 and Elixir 1.3.2 running Phoenix 1.2.0:

[error] fs does not support the current operating system

Is the error message above benign?
(I've been redirected to here from phoenixframework/phoenix#920 )

@jj1bdx Yeah it is benign. There is at least a way to configure Brunch to use polling (add this to your brunch config)

watcher: {usePolling: true}

But can't really get the live channels update working without some lifting here.

@dch Do you think we can tackle this one?

kuon commented

@jj1bdx basically you won't get live reload if you do development under FreeBSD for now. I have not been affected in production.

I've added rudimentary support for fswatch (it becoming the only backend) in erlfsmon. Take a look, perhaps the backend could be similarly used in fs (I haven't tested it anywhere but osx, it uses the sh -c '$0; read; kill' trick, so i'm not sure how this will work out on windows).

kuon commented

@proger Any update on this issue? Maybe I can help if you give me some context? (I am a bit lost as to what exactly has to be done)

This is the only thing preventing me from developing on FreeBSD via SSH from windows.

@kuon As a temporary fix, try to make the inotify support work using https://github.com/wulf7/libinotify-kqueue shim. fs might needs some patches to work.

To this issue: Making a proper kqueue/kevent backend is the best way to go. Less brittle at the expense of duplicating some effort. Ancedotal evidence: our team once had to rip out a fsevent file notification monitor backend in another language that communicated with an external process because it leaked those processes and wasted METRIC TONS of resources, slowing down development.

kuon commented

@steakknife If we are going to throw in a dependency, I'd go for fswatch.

@kuon Then feel free to implement it. Good luck!

Just in case, to simply use fswatch you need 25 LoC and erlsh:

https://github.com/proger/erlfsmon#the-core

@proger fswatch is licensed under GPL 3. That's fine for most hobbyists and some local development, but it's unusable for anything real. watchman has a much better license, platform interop and larger community; 3rd-party bindings (untested).

@steakknife Great find! I was not aware of this tool. Fortunately, it's not a lot of work to add support for watchman ;)

kuon commented

Watchman BSD support is not actively developed. See the note at the top: https://facebook.github.io/watchman/docs/install.html

kuon commented

@steakknife We could add fswatch support without bundling it. And if it's not in the PATH, just print a message.

@kuon If you need BSD watchman support, then feel free to volunteer. :)

what about degrading the message from [error] to [warning] in the meanwhile:
[warning] fs does not support the current operating system: automatic code reloading might not work
or similar?

sorry for the not re- or pre-thought pull request.

https://github.com/duke-m/kqclient

can we try to use this as a base for the fs-bsd-port?

sys/kq.erl sketch:

known_events() -> [renamed, removed, modified, undefined].

start_port(Path, Cwd) ->
    Path1 = filename:absname(Path),
    Args = [Path1],
    erlang:open_port({spawn_executable, find_executable()},
        [stream, exit_status, {line, 16384}, {args, Args}, {cd, Cwd}]).

line_to_event(Line) ->
    {match, [Path, F]} = re:run(Line, re(), [{capture, all_but_first, list}]),
    Flag = [convert_flag(F)],
    {Path, Flag}.

convert_flag("WRITE") -> modified;
convert_flag("DELETE") -> removed;
convert_flag("RENAME") -> renamed;
convert_flag(_) -> undefined.

re() ->
    case get(kq_re) of
        undefined ->
            {ok, R} = re:compile("^(.*) ([A-Z]+) .* .*$", [unicode]),
            put(kq_re, R),
            R;
        V -> V
    end.