Многопоточный выполнение логики кода с использование тг-бота
Написал тг-бота через pyTelegramBotAPI, который служит для получения выгодных предложение по закупке предметов. Требуется так, чтобы для каждого пользователя, в зависимости от его фильтров, программа выполнялась по-своему, это работает но получается так, что из всего массива объектов, одному пользователю отсылается одна часть, а другому - другая.
bot.py
Создание потоков:
def run_csm(message):
user_id = message.from_user.id
users_data = read_json('users_data.json')
if not users_data[str(user_id)]['filters']['check']:
bot.send_message(user_id, 'Фильтры не установлены')
else:
users_data[str(user_id)]['run-csm'] = True
markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
item_btn1 = types.KeyboardButton('Остановить')
markup.add(item_btn1)
users_data[str(user_id)]['state'] = 'csm-menu'
write_json('users_data.json', users_data)
bot.send_message(user_id, 'Программа запущена. Ожидайте.', reply_markup=markup)
t = threading.Thread(target=GetItemForBuy.get_item_from_csm, args=(bot, message))
t.start()
GetitemForBuy.py
Код, который выполняется после создания потока:
def get_item_from_csm(bot, message):
user_id = message.from_user.id
users_data = read_json('users_data.json')
exchange_rate = get_exchange_rate()
min_price = users_data[str(user_id)]['filters']['min-cost'] / exchange_rate
url = f'https://cs.money/1.0/market/sell-orders?limit=60&minPrice={min_price}&order=desc&sort=insertDate'
ua = UserAgent()
while True:
users_data = read_json('users_data.json')
if users_data[str(user_id)]['run-csm'] is False:
break
try:
time.sleep(0.1)
response = requests.get(url=url, headers={'User-Agent': ua.random})
Дальше выполняются запросы и в дальнейшем вызывается send_new_items(bot, user_id, users_data, exchange_rate)
В send_new_items() выполняется подстановка данных, которые нужно отправить в переменные и затем они объединяются, где далее отправляются пользователю по id.
if item_cost_steam_discount >= (users_data[str(user_id)]['filters']['percent-benefit'] / 100):
try:
if str(user_id) == '1479852440':
print(1)
else:
print(2)
# Отправляем сообщение с использованием HTML разметки для ссылки
bot.send_photo(chat_id=user_id,
photo=item_image,
caption=item_info,
parse_mode='HTML')
print('Информация отправлена')
users_data.json:
{
"5534714555": {
"free-time": "",
"filters": {
"check": true,
"min-cost": 1.0,
"max-cost": 1000000.0,
"percent-benefit": 26.0
},
"state": "csm-menu",
"run-csm": true
},
"1479852440": {
"free-time": "",
"filters": {
"check": true,
"min-cost": 1.0,
"max-cost": 1000000.0,
"percent-benefit": 26.0
},
"state": "csm-menu",
"run-csm": true
}
}
И самое главное - вывод:
{'name': 'StatTrak™ SG 553 | Dragon Tech (Field-Tested)', 'cost': '$1.46 USD'} 43
1
Информация отправлена
{'name': 'Sticker | Into The Breach | Paris 2023', 'cost': '$0.03 USD'} 33
1
Информация отправлена
{'name': 'Sticker | ESPADA | 2020 RMR', 'cost': '$0.03 USD'} 33
2
Информация отправлена
{'name': 'AUG | Sweeper (Field-Tested)', 'cost': '$0.04 USD'} 50
1
Информация отправлена
{'name': 'MAG-7 | Rust Coat (Field-Tested)', 'cost': '$0.04 USD'} 50
2
Информация отправлена
{'name': 'StatTrak™ USP-S | Torque (Field-Tested)', 'cost': '$2.49 USD'} 31
1
Информация отправлена
{'name': 'Sticker | FaZe | 2020 RMR', 'cost': '$0.09 USD'} 33
2
Информация отправлена
{'name': 'AK-47 | Uncharted (Well-Worn)', 'cost': '$0.84 USD'} 43
1
Информация отправлена
{'name': 'USP-S | Flashback (Field-Tested)', 'cost': '$0.63 USD'} 30
2
Как можно заметить, то цифра 1 и 2 означают как раз таки пользователей, которым отправляются предметы, ну я не понимаю, почему же каждому пользователю отправляется по одному уникальному предмету, хотя предмет должен отсылаться тому и тому, т.к. фильтры одинаковые и работают в параллельных потоках.
Ответы (2 шт):
if users_data[str(user_id)]['run-csm'] is False:
break
Тебе следует использовать continue, вместо break, если ты хочешь, чтобы цикл продолжался
if users_data[str(user_id)]['run-csm'] is False:
continue
Я обнаружил свою ошибку. По сути, я создавал новые потоки для каждого пользователя, но DataCsm и SentItems были глобальными. Благодаря этому данные из всех потоков были сохранены в один. Я удалил глобальные переменные и создал свои для каждого потока, все заработало как надо. Если вам нужно использовать новые данные для каждого потока, поместите их в вызов, а не делайте глобальными, ошибка новичка)