I built a little function based on the tutorial using nodejs. It returns {"status":"done"} as intended.
After changing the code, it keeps returning this data when it shouldn't.
This is more a question than a bug report: how can I make sure the latest code is used after a rebuild/redeploy?
After changing the code, it should return different data: {"licenseKey":"<something>"}.
It keeps returning {"status":"done"} no matter how often I rebuild/redeploy.
docker version (e.g. Docker 17.0.05 ):Docker version 18.06.0-ce-rc1
Docker swarm
Ubuntu 18.04 LTS
The code currently looks like this:
module.exports = (context, callback) => {
let licenseKey = null;
try {
const hosts = JSON.parse(context).hosts;
if (hosts.length > 0) {
licenseKey = key.generate(hosts); // This simply returns a string
}
} catch (e) {}
callback(undefined, { licenseKey });
};
I've experienced this before as well when running on Swarm. At the time, I was able to find an issue on the docker/swarm repo, but can't seem to find it now.
What I've done to prevent that is to use version tags on the images when you re-deploy.
So, your func.yml would look like this:
functions:
func:
lang: node
image: func:0.1
Then, when you update the code, also update the func.yml to a new version:
functions:
func:
lang: node
image: func:0.2
Also, make sure you're running the build command after you update your code!
faas-cli build -f func.yml
then, re-deploy:
faas-cli deploy -f func.yml
Where func.yml is your function's yml file
Derek add label: question
Thanks. I defs build then deploy:
faas-cli build -f license.yml && faas-cli deploy -f license.yml
I'm gonna give your suggestion a try. It's a bit of a hassle, but if it works I'm happy for now. :)
just making sure! :smile:
I understand that it can be a bit of trouble. It's not consistent either. I haven't had it happen recently, but every once in a while it pops up again...
You're absolutely right for pointing it out. Pet peeve at previous job was 'Did you actually git push?' followed by a pause and answered with 'erm, no.' :)
Unfortunately, your suggestion doesn't prevent the problem. I can see that the image name is actually used in the build:
```Successfully built d9a3cc8f3b70
Successfully tagged license:0.3
Image: license:0.3 built.
[0] < Building license done.
[0] worker done.
Deploying: license.
Function license already exists, attempting rolling-update.
Deployed. 200 OK.
URL: http://127.0.0.1:8080/function/license
But my test command:
curl http://127.0.0.1:8080/function/license -H 'Content-Type: application/json' --data-binary '{"hosts":["AABBCCCDDDXXX"]}'
```
still returns the old data:
{"status":"done"}
I'm actually glad you've seen this happen before. Means that I'm not going nuts. ;)
I don't know if this is of interest, but I ran a docker ps, and I noticed that the image is available, but the PORTS column is empty for this particular image:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1416a05edc29 license:0.3 "fwatchdog" 11 minutes ago Up 11 minutes (healthy) license.1.mta7jmj4i3sd6fcjao64y808u
I found the problem, and I believe apologies (from me) are in order. Turns out that my main file was called index.js and not handler.js.
It's too late to check, but either I left handler.js after the initial build (from the tutorial) and started working in the copied index.js, or faas somehow remembers it if you've used it once. I'm not sure.
Problem solved, and sorry for wasting your time @burtonr ....
No worries! Glad you got it sorted!
I can quite easily reproduce it. Which begs the question: is it expected behaviour that a faas function keeps working even when it no longer has a handler.js?
Here's how to reproduce it:
$ faas new callme --lang node
$ faas build -f callme.yml
$ faas deploy -f callme.yml
Now invoke the new function. I used curl:
$ curl http://127.0.0.1/function/callme
{"status":"done"}
Now, replace handler.js with 'index.js`, maybe change the value of the return object to 'aaaaallll done' so you would be able to see a difference, rebuild and redeploy:
$ mv callme/handler.js callme/index.js
$ faas build -f callme.yml
$ faas deploy -f callme.yml
Invoke again:
$ curl http://127.0.0.1/function/callme
{"status":"done"}
Nothing's changed...
What do you reckon? I'm happy to open a bug report if you feel that's needed. :)
Update: even removing the build directory for callme and rebuilding does not solve the problem. In fact, it happily creates handler.js, even though it's not in the source directory any more...
I think this is more of a node related thing to look for index.js if you are just specifying a directory for your handler, right? Unless you are being explicit in pointing to handler.js.
provider:
name: faas
gateway: http://127.0.0.1:8080
functions:
hello:
lang: node
handler: ./hello <-- directory
image: hello
Node docs:
If there is no package.json file present in the directory, then Node.js will attempt to load an index.js or index.node file out of that directory.
LOAD_AS_DIRECTORY(X)
1. If X/package.json is a file,
a. Parse X/package.json, and look for "main" field.
b. let M = X + (json main field)
c. LOAD_AS_FILE(M)
d. LOAD_INDEX(M)
Which the template has a main field pointing to handler.js, but since it isn't available it falls back to index.js.
Maybe you're right. But I honestly can't get my head around the fact that it somehow finds a handler.js and build a working function. Erm. It's no longer in the source directory... However, if everything works as intended, then I'm happy to leave it at that. :)