I know there are a few questions about this. But I don't think this case has been covered.
I've simply made a bit of code to install and then start a W10 Elasticsearch service if it isn't already up and running. When I run this when the ES service has not been installed I get an ES internal error at requests.get( ...)
(and it kills the script).
But if I run the script again the service is recognised as running fine, and requests.get( ...)
returns OK, with no internal ES error thrown. This shows that the script does indeed both install and start the service... but for some reason sending the URL request immediately afterwards (same run/process) causes a problem.
Incidentally, if I simply stop the service, so it is still installed, but stopped, and then run the script, again it fouls up (i.e. after simply starting the service) and the error occurs.
What's more, I'm pretty sure that this wasn't happening yesterday when I started experimenting with this. For this reason I have gone back in my repo to the simplest implementation, in the hope that someone can explain what's up and how (whether) it can be resolved. I.e. I want to be able to install the service, start it, and then start using it, all from within the same Python run (process).
Here is an MRE:
import os, sys, io, requests, psutil, elasticsearch
def install_and_start_es_service():
def get_service(name):
service = None
try:
service = psutil.win_service_get(name)
service = service.as_dict()
except Exception as ex:
print( f'service {name} not yet installed' )
return service
try:
destination_extract_dir = 'D:/apps/ElasticSearch'
es_bin_dir = destination_extract_dir + '/elasticsearch-7.10.2/bin'
service = get_service('elasticsearch-service-x64')
if service and service['status'] == 'running':
# best case scenario
return True
# at this point we will need to try to either start or install the service.
# to do either of those we need to ensure that the ES bin directory is in place
if not os.path.isdir( es_bin_dir ):
print( 'ES bin dir not found' )
return False
os.chdir( es_bin_dir )
if not service:
# can we install the service?
print( f'before service.bat install...' )
os.chdir( es_bin_dir )
os.system( 'elasticsearch-service.bat install' )
print( f'after service.bat install...' )
service = get_service('elasticsearch-service-x64')
if not service:
print( 'something went wrong trying to install the ES service')
return False
# can we start the service?
print( f'before service.bat start...' )
os.chdir( es_bin_dir )
os.system( 'elasticsearch-service.bat start' )
print( f'after service.bat start...' )
service = get_service('elasticsearch-service-x64')
if service == None or service['status'] != 'running':
print( 'something went wrong trying to start the ES service')
return False
except Exception as e:
logger.exception( 'unexpected exception thrown while trying to install and start ES service' )
return False
return True
es_started = install_and_start_es_service()
print( f'ES started? {es_started}')
if not es_started:
sys.exit()
r = requests.get('http://localhost:9200')
print( f'type r {type(r)}') # requests.models.Response
This is a typical end of the stacktrace when things go wrong:
File "D:\more software projects\python_venv\env\lib\site-packages\requests\adapters.py", line 516, in send
raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPConnectionPool(host='localhost', port=9200): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x0000020842FAAD30>: Failed to establish a new connection: [WinError 10061] No connection could be made because the target machine actively refused it'))
Note that this is an internal ES error... i.e. the trace does not originate from a line of my code. However, I can work out that the requests.get( ...
line is causing it.
Edit
leandrojmp helpfully suggests a non-zero waiting period might be required. I should have mentioned that I had tried this with time.sleep( 5 )
. I'd have thought that should be more than enough... but am going to try a bit more experimentation along those lines...
The error you are getting is an error from the request library because your elasticsearch instance was not ready yet.
No connection could be made because the target machine actively refused it
This means that your elasticsearch was running, the port was open, but it wasn't ready to answer to requests yet because it was still starting.
From the moment where you start the Elasticsearch service in your windows machine to the moment where the elasticsearch service can really answer to requests, it could take a few seconds, sometimes a few minutes.
You will need to wait some time to make a request after you start the service, or implement some logic to keep trying until it can talk to your elasticsearch instance.
If you try to make a request immediately after you start the service, your script will probably fail, the service needs some time to boot up the JVM and start the elasticsearch application.