firebase-tools icon indicating copy to clipboard operation
firebase-tools copied to clipboard

Emulator error `Error: socket hang up`

Open jhuleatt opened this issue 2 years ago • 24 comments

On my m1 mac, I get the following error when emulating a function with the BigQuery python SDK:

>  objc[122]: +[__NSCFConstantString initialize] may have been in progress in another thread when fork() was called.
>  objc[122]: +[__NSCFConstantString initialize] may have been in progress in another thread when fork() was called. We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug.
⬢  functions: Failed to handle request for function us-central1-commontrees
⬢  functions: Failed to start functions in /Users/jhuleatt/projects/io-python/functions: Error: socket hang up

here's the function code:

from firebase_functions import https_fn
from google.cloud import bigquery
import json

@https_fn.on_request(timeout_sec=20)
def commontrees(req: https_fn.Request) -> https_fn.Response:
    client = bigquery.Client()
    query = """
        SELECT spc_latin, spc_common, COUNT(spc_latin) as num_specimens
        FROM `bigquery-public-data.new_york_trees.tree_census_2015`
        WHERE SPC_LATIN <> ''
        GROUP BY spc_latin, spc_common
        ORDER BY num_specimens DESC
        LIMIT 50
    """
    query_job = client.query(query)

    common_trees = [];
    for row in query_job:
        common_trees.append({
            "scientificName": row['spc_latin'],
            "commonName": row['spc_common'],
            "count": row['num_specimens']
        })
    return https_fn.Response(json.dumps(common_trees),  mimetype='application/json')

jhuleatt avatar Mar 06 '23 18:03 jhuleatt

It seems like this might be specific to MacOS. Following the advice in this StackOverflow answer fixes the issue, but I'm not sure if it is something we want to recommend.

jhuleatt avatar Mar 06 '23 18:03 jhuleatt

Having the same issue. Above solution did not work for me.

  >  objc[61886]: +[__NSCFConstantString initialize] may have been in progress in another thread when fork() was called.
  >  objc[61886]: +[__NSCFConstantString initialize] may have been in progress in another thread when fork() was called. 
 We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on 
 objc_initializeAfterForkError to debug.

` from firebase_functions import firestore_fn, https_fn
from firebase_admin import initialize_app, firestore
import google.cloud.firestore
from langchain.llms import OpenAI

app = initialize_app()

@https_fn.on_request()
def askQuestion(req: https_fn.Request) -> https_fn.Response:

    projectId = req.args.get("projectId")
    prompt = req.args.get("prompt")

    if projectId is None:
        return https_fn.Response("No projectId", status=400)
    if prompt is None:
        return https_fn.Response("No projectId", status=400)



    llm = OpenAI(temperature=0)
    print(llm(prompt))
  
    return https_fn.Response(f"Success!", status=200) `

jamescash avatar May 21 '23 20:05 jamescash

@jhuleatt Do you mind sharing your fix? This is not working for me:

import os os.environ['OBJC_DISABLE_INITIALIZE_FORK_SAFETY'] = 'YES'

jamescash avatar May 24 '23 14:05 jamescash

Starting the emulator with this option does the trick for me:

export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES

taeold avatar Jun 14 '23 21:06 taeold

@jhuleatt Could you provide a reproducible example so that I may test this further?

exaby73 avatar Jul 17 '23 08:07 exaby73

I'm running into the same issue.

To repro, create a new Firebase Function module (using firebase init functions, and then change the code for on_request_example like this:

import requests

@https_fn.on_request()
def on_request_example(req: https_fn.Request) -> https_fn.Response:
  response = requests.get("https://www.google.com")
  return https_fn.Response("Hello world!")

This results in the following output:

⬢  functions: Failed to handle request for function us-central1-on_request_example
⬢  functions: Failed to start functions in helloworld: Error: socket hang up

peterfriese avatar Aug 23 '23 19:08 peterfriese

Hello @peterfriese. Unfortunately, I am not able to reproduce this issue. I tried the following code:

import requests
from firebase_functions import https_fn, options
from firebase_admin import initialize_app

options.set_global_options(max_instances=10)

initialize_app()


@https_fn.on_request()
def on_request_example(req: https_fn.Request) -> https_fn.Response:
    response = requests.get("https://www.example.com") # Tried with google.com as well
    return https_fn.Response("Hello world!")

The following is my requirements.txt:

firebase-functions==0.1.1

My python version is Python 3.11.4

exaby73 avatar Aug 28 '23 06:08 exaby73

Solved same kind of error by overwriting the unused function.

import requests

@https_fn.on_request()
def the_deleted_function_name(req: https_fn.Request) -> https_fn.Response:
  pass

It seems emulator tries to find cached function that doesn't exist.

arcoyk avatar Sep 20 '23 17:09 arcoyk

@exaby73

Unfortunately, I am not able to reproduce this issue. I tried the following code:

Did you try on a Mac? I think I'm also using that OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES

antont avatar Sep 21 '23 05:09 antont

@antont I am on an M1 mac, without the OBJC_DISABLE_INITIALIZE_FORK_SAFETY flag set

exaby73 avatar Sep 22 '23 10:09 exaby73

@exaby73 I am on an M1 mac, without the OBJC_DISABLE_INITIALIZE_FORK_SAFETY flag set

Ok. After OS upgrade and related restart, I didn't have the env var back yet, and again got that:

>  objc[26098]: +[__NSCFConstantString initialize] may have been in progress in another thread when fork() was called.
>  objc[26098]: +[__NSCFConstantString initialize] may have been in progress in another thread when fork() was called. We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug.
i  Request to function failed: Error: socket hang up

Then setting the flag fixed it.

I'll keep this env now so can provide details about versions etc. later if that helps.

antont avatar Sep 22 '23 11:09 antont

Hey @antont. I'm wondering if you can reproduce this using Node as well. Since I can't reproduce this myself, I am unable to confirm it

exaby73 avatar Oct 09 '23 12:10 exaby73

Hey @jhuleatt. We need more information to resolve this issue but there hasn't been an update in 7 weekdays. I'm marking the issue as stale and if there are no new updates in the next 3 days I will close it automatically.

If you have more information that will help us get to the bottom of this, just add a comment!

google-oss-bot avatar Dec 19 '23 02:12 google-oss-bot

Since there haven't been any recent updates here, I am going to close this issue.

@jhuleatt if you're still experiencing this problem and want to continue the discussion just leave a comment here and we are happy to re-open this.

google-oss-bot avatar Dec 22 '23 02:12 google-oss-bot

Exporting those two variables fixed the problem for me:

export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES
export no_proxy=*

AgaMiko avatar Mar 04 '24 13:03 AgaMiko

Still an issue with me and my M1 Mac.

Going to try a couple of the fixes, don't really have a short example to reproduce.

EDIT: export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES Allowed the emulator python cloud function to work

b0ot avatar Mar 23 '24 20:03 b0ot

Is this now documented somewhere?

Am I correct to summarize this as:

  • MacOS
  • M1 chip (M2? M3? Intel?)
  • running Python cloud functions in the Emulator Suite
  • need to set env var export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES in order for the (Python engine ??) to run properly

gregfenton avatar Mar 30 '24 00:03 gregfenton

Am I correct to summarize this as:

  • MacOS
  • M1 chip (M2? M3? Intel?)
  • running Python cloud functions in the Emulator Suite
  • need to set env var export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES in order for the (Python engine ??) to run properly

Yes that is correct, at least for my case (Macbook Air, M1, 2020) Until I set that export, I was unable to have my python cloud functions run successfully in the Firebase Emulator.

b0ot avatar Mar 30 '24 07:03 b0ot

Exporting those two variables fixed the problem for me:

export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES
export no_proxy=*

this fixes the issue on newer Mac

theConstantHustler avatar Sep 22 '24 16:09 theConstantHustler

I also got the same issue with a brand new Macbook Pro M4

export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES export no_proxy=*

Unfortunately, this did not fix the issue for me

I also tried to migrate the function to the functions-framework and got the same behavior there as well. While debugging the issue a bit further, I noticed that the --debug-flag fixes the issue with the difference being that it is running the Flask server directly instead of using gunicorn.

It seems that gunicorn is actually the issue which is creating multiple threads with fork which is a known issue in MacOS (see https://github.com/python/cpython/issues/77906#issuecomment-1093788337, https://github.com/php/php-src/issues/11818). It has even been flagged in March 2022 but has not been fixed yet.

Since this bug has a major impact on the Firebase Function Emulator on MacOS, I believe that adapting firebase-tools makes a lot of sense.

As the debug flag of the functions-framework is set to false in the Firebase Emulator, I think that it might be reasonable to add a flag to firebase-tools and potentially also to functions-framework that disables gunicorn without running Flask in debug-mode. @colerogers what do you think? (tagging you since this issue is assigned to you)

ThomasKaar avatar Feb 23 '25 22:02 ThomasKaar

@ThomasKaar @colerogers Running into the same issue as well.

PSchmiedmayer avatar Feb 24 '25 17:02 PSchmiedmayer

As the debug flag of the functions-framework is set to false in the Firebase Emulator, I think that it might be reasonable to add a flag to firebase-tools and potentially also to functions-framework that disables gunicorn without running Flask in debug-mode. @colerogers what do you think? (tagging you since this issue is assigned to you)

Thinking through this, we could pipe through the --debug flag to functions-framework - maybe worth testing out.

joehan avatar Feb 25 '25 18:02 joehan

It might be worth a try to see whether this fixes the issue, but setting the debug-flag to False is explicitly done to prevent reloading the Flask server, which is why I believe that introducing a new flag might be more suitable as a fix for MacOS users.

see https://github.com/firebase/firebase-tools/blob/master/src/emulator/functionsEmulator.ts#L1660-L1669

    const childProcess = runWithVirtualEnv(args, backend.functionsDir, {
      ...process.env,
      ...envs,
      // Required to flush stdout/stderr immediately to the piped channels.
      PYTHONUNBUFFERED: "1",
      // Required to prevent flask development server to reload on code changes.
      DEBUG: "False",
      HOST: "127.0.0.1",
      PORT: port.toString(),
    });

ThomasKaar avatar Feb 25 '25 19:02 ThomasKaar

This and the Python debugging are two killer issues. Which it could be prioritized

kornha avatar May 09 '25 21:05 kornha

I'm experiencing significant issues with a large project after updating MacOS - approximately half of the Firebase functions are no longer working. This is concerning given that Firebase is a critical infrastructure service that many businesses depend on for commercial applications.

jgavazzisp avatar Jul 04 '25 00:07 jgavazzisp