The third fundamental Effection operation is [`resource()`][resource]. It can
seem a little complicated at first, but the reason for its existence is
rather simple. Sometimes there are operations which meet the following criteria:

1. They are long running
1. We want to be able to interact with them while they are running

As an example, let's consider a program that creates a Socket and sends
messages to it while it is open. This is fairly simple to write using regular
operations like this:

``` javascript
import { main, once } from 'effection';
import { Socket } from 'net';

await main(function*() {
  let socket = new Socket();
  socket.connect(1337, '127.0.0.1');

  yield* once(socket, 'connect');

  socket.write('hello');

  socket.close();
});
```

This works, but there are a lot of details we need to remember in order to use
the socket safely. For example, whenever we use a socket, we don't want to have
to remember to close it once we're done. Instead, we'd like that to happen
automatically. Our first attempt to do so might look something like this:

``` javascript
import { once, suspend } from 'effection';
import { Socket } from 'net';

export function* useSocket(port, host) {
  let socket = new Socket();
  socket.connect(port, host);

  yield* once(socket, 'connect');

  try {
    yield* suspend();
    return socket;
  } finally {
    socket.close();
  }
}
```

But when we actually try to call our `useSocket` operation, we run into a
problem: because our `useSocket()` operation suspends, it will wait around
forever and never return control back to our main.

``` javascript
import { main } from 'effection';
import { useSocket } from './use-socket';

await main(function*() {
  let socket = yield* useSocket(1337, '127.0.0.1'); // blocks forever
  socket.write('hello'); // we never get here
});
```

Remember our criteria from before:

1. Socket is a long running process
1. We want to interact with the socket while it is running by sending messages
to it

This is a good use-case for using a resource operation. Let's look at how we can
rewrite `useSocket()` as a resource.

``` javascript
import { once, resource } from 'effection';

export function useSocket(port, host) {
  return resource(function* (provide) {
    let socket = new Socket();
    socket.connect(port, host);

    yield* once(socket, 'connect');

    try {
      yield* provide(socket);
    } finally {
      socket.close();
    }
  }
}
```

Before we unpack what's going on, let's just note that how we call `useSocket()`
has not changed at all, only it now works as expected!

``` javascript
import { main } from 'effection';
import { useSocket } from './use-socket';

await main(function*() {
  let socket = yield* useSocket(1337, '127.0.0.1'); // waits for the socket to connect
  socket.write('hello'); // this works
  // once `main` finishes, the socket is closed
});
```

The body of a resource is used to *initialize* a value and make it
available to the operation from which it was called. It can do any
preparation it needs to, and take as long as it wants, but at some
point, it has to "provide" the value back to the caller. This is done
with the `provide()` function that is passed as an argument into each
resource constructor. This special operation, when yielded to, passes
control _back_ to the caller with our newly minted value as its result.


However, its work is not done yet. The `provide()` operation will remain
suspended until the resource passes out of scope, thus making sure that
cleanup is guaranteed.

>💡A simple mantra to repeat to yourself so that you remember how resources work
> is this: resources ___provide___ values.

Resources can depend on other resources, so we could use this to make a socket
which sends a heart-beat every 10 seconds.

``` javascript
import { main, resource, spawn } from 'effection';
import { useSocket } from './use-socket';

function useHeartSocket(port, host) {
  return resource(function* (provide) {
    let socket = yield* useSocket(port, host);

    yield* spawn(function*() {
      while (true) {
        yield* sleep(10_000);
        socket.send(JSON.stringify({ type: "heartbeat" }));
      }
    });

    yield* provide(socket);
  });
}

await main(function*() {
  let socket = yield* useHeartSocket(1337, '127.0.0.1'); // waits for the socket to connect
  socket.write({ hello: 'world' }); // this works
  // once `main` finishes:
  // 1. the heartbeat is stopped
  // 2. the socket is closed
});
```

The original socket is created, connected, and set up to pulse every ten
seconds, and it's cleaned up just as easily as it was created.

Note that the [`ensure()`][ensure] operation is an appropriate mechanism to
enact cleanup within resources as well. While a matter of preference, the
`useSocket()` resource above could also have been written as:

``` javascript
import { ensure, once, resource } from 'effection';

export function useSocket(port, host) {
  return resource(function* (provide) {
    let socket = new Socket();
    yield* ensure(() => { socket.close(); });

    socket.connect(port, host);

    yield* once(socket, 'connect');
    yield* provide(socket);
  }
}
```

Resources allow us to create powerful, reusable abstractions which are also able
to clean up after themselves.

[tasks]: /docs/guides/tasks
[operation]: /api/v3/Operation
[resource]: /api/v3/resource
[ensure]: /api/v3/ensure
