-
Notifications
You must be signed in to change notification settings - Fork 63
Open
Labels
bugSomething isn't workingSomething isn't workingnewThe item has just been created and was not seen by MSTR developer yetThe item has just been created and was not seen by MSTR developer yet
Description
Description
Sometimes, server does not respond : client script hangs until being killed
MicroStrategy Support Case
CS0944624 Implementing safe calls with mstrio
Steps To Reproduce
Difficult to reproduce since it works most of the time. When server does not respond there is no default timeout (AFAIK).
Code Snippet
Below an example of a custom function which may hang undefinitly
def create_user(conn: Connection, row: pd.Series, membership_id: str) -> str:
"""
Creates a new user in the system using the provided connection, user data, and membership ID.
Args:
conn: Database connection object.
row (dict): Dictionary containing user information with keys 'user', 'fullname', 'ldaplink', and 'trutedlogin'.
membership_id: The ID of the membership to assign to the user.
Returns:
str: "Created" if the user was successfully created,
"Already Exists" if the user already exists,
or an error message string if an exception occurred.
Logs:
- Info log when a user is created or already exists.
- Error log if user creation fails for another reason.
"""
try:
User.create(
connection=conn,
username=row["user"],
full_name=row["fullname"],
ldapdn=row["ldaplink"],
trust_id=row["trutedlogin"],
memberships=[membership_id],
standard_auth=False,
)
logger.info(f"User created: {row['user']}")
return "Created"
except Exception as e:
if "already exists" in str(e):
logger.info(f"User already exists: {row['user']}")
return "Already Exists"
logger.error(f"Error creating user: {e}")
return f"Error: {e}"
Additional Context (optional)
We developed a workaround through a decorator in our script below
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
for attempt in range(retries):
try:
return func(*args, **kwargs)
except (requests.exceptions.Timeout, requests.exceptions.ConnectionError) as e:
logger.warning(f"Attempt {attempt+1} failed: {e}")
time.sleep(delay)
except Exception as e:
logger.error(f"Unhandled exception: {e}")
break
return "Error: API server not responding"
return wrapper
return decorator
We use it on the previous code like below
@safe_call(retries=3, delay=2)
def create_user(conn: Connection, row: pd.Series, membership_id: str) -> str:
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't workingnewThe item has just been created and was not seen by MSTR developer yetThe item has just been created and was not seen by MSTR developer yet