heavycharged
эта защита от того, чтобы юзеры не дергали закрытие 100 раз
heavycharged
т.е. с разных мест прилетел stop(), но он выполнится один раз
Nikita
во-во
Artem
эта защита от того, чтобы юзеры не дергали закрытие 100 раз
что б сделать защиту, тебе нужно не ошибку, а панику кидать
heavycharged
зачем мне кидать панику, ситуация полностью контролируемая
heavycharged
зачем тут паника?
Nikita
зачем тут паника?
тебе же уже сказали юзать sync.Once, что тут еще обсуждать?)
Artem
а логика подразумевает 1
heavycharged
тебе же уже сказали юзать sync.Once, что тут еще обсуждать?)
окей, заюзаю sync.Once. забыл чето про него.
heavycharged
нет, если закрывают много раз
это раннер определенных задач, он делает броадкаст в хаб где висят клиенты на вебсокете, каждый из них может сказать "СТОП" задаче, первый раз я стопаю задачу и говорю клиенту "Ок, задача останавливается". Все последующие задачи я возвращаю юзеру "Задача уже останавливается", до тех пор задача полностью не остановится, последующие вызовы стоп будут возвращать ошибку что задача не обнаружена. Мне кажется паника тут избыточна. Зачем её делать, чтобы потом ловить, если можно сразу ошибку вернуть.
heavycharged
а то что происходит внутри sync.Once это concurrent-safe? т.е. я могу из этой функции через замыкание менять состояние других переменных?
heavycharged
потому как мне нужен механизм уведомлений, что задача уже останавливается..
heavycharged
окай, спасибо!
Vladislav
да, там mx стоит внутри
Стоп. Если переменная не защищена и используется снаружи, то нельзя по-моему.
Artem
какую-то сложную штуку тут городят
Progmer
Всем привет. Задача такая. Необходимо переписать код получения данных от БД с преобразованием полученного значения в объект с кастомной структурой, который разросся и хочется все это убрать в одну функцию Из БД прилетает исключительно JSON, он валидный и все с этим норм Кастомных объектов может быть много, и есть много мест где нужно получить эти кастомные объекты Пока получилось такое: Сама функция (тут интересен момент преобразования json строки в объект): func (s *myService) processDbRequest(query string, response interface{}) (interface{}, error) { row, err := s.query(query) if err != nil { return nil, err } var jsonStr []byte if err := row.Scan(&jsonStr); err != nil { return nil, err } if err := json.Unmarshal(jsonStr, &response); err != nil { return nil, err } return response, nil } Есть код где я дергаю эту функцию: response := MyCustomType{} response, error := s.processDbRequest("SELECT ... FROM ...", response) и на выходе мне нужен мой кастомный тип: response.(MyCustomType) Проблема в том, что json.Unmarshal отрабатывает внутри функции и на выходе дает map[string]interface{}, который потом невозможно преобразовать в мой кастомный тип response.(MyCustomType) Как можно организовать код, чтобы мне на выходе получить объект нужного мне типа? Видится пока только вызов json.Unmarshal после выполнения функции, но это как-то костыльно чтоли.
Artem
я б копипастнул с http.Server.Shutdown()
Artem
поменяй на 1. func (s *myService) processDbRequest(query string, response interface{}) (error) 2. return nil 3. err := s.processDbRequest("SELECT ... FROM ...", &response)
Artem
Всем привет. Задача такая. Необходимо переписать код получения данных от БД с преобразованием полученного значения в объект с кастомной структурой, который разросся и хочется все это убрать в одну функцию Из БД прилетает исключительно JSON, он валидный и все с этим норм Кастомных объектов может быть много, и есть много мест где нужно получить эти кастомные объекты Пока получилось такое: Сама функция (тут интересен момент преобразования json строки в объект): func (s *myService) processDbRequest(query string, response interface{}) (interface{}, error) { row, err := s.query(query) if err != nil { return nil, err } var jsonStr []byte if err := row.Scan(&jsonStr); err != nil { return nil, err } if err := json.Unmarshal(jsonStr, &response); err != nil { return nil, err } return response, nil } Есть код где я дергаю эту функцию: response := MyCustomType{} response, error := s.processDbRequest("SELECT ... FROM ...", response) и на выходе мне нужен мой кастомный тип: response.(MyCustomType) Проблема в том, что json.Unmarshal отрабатывает внутри функции и на выходе дает map[string]interface{}, который потом невозможно преобразовать в мой кастомный тип response.(MyCustomType) Как можно организовать код, чтобы мне на выходе получить объект нужного мне типа? Видится пока только вызов json.Unmarshal после выполнения функции, но это как-то костыльно чтоли.
^
Progmer
Так, ну я теперь не получаю из функции ответ от БД. В чем соль?
Artem
он лежит в response
Artem
json.Unmarshal(jsonStr, &response) положит его response снаружи
Progmer
А, по ссылке же, ща чекну
Artem
ток нужно поправить json.Unmarshal(jsonStr, &response) на json.Unmarshal(jsonStr, response)
heavycharged
Стоп. Если переменная не защищена и используется снаружи, то нельзя по-моему.
да, нельзя. можно попасть в кейс, когда первый if сработает, но уже запущен sync.Once
heavycharged
т.е. if isStopping { return errors.New("is stopping") } once.Do(func() { isStopping = true // закрываем })
Nikita
heavycharged
Да тут уже ясно что данный вариант не вариант
heavycharged
Мьютексы только
Nikita
Мьютексы только
Походу ясно это только тебе
heavycharged
А тебе не ясно?
Nikita
А тебе не ясно?
Ну мля, в sync.Once и так мютекс лежит, зачем тебе изобретать велосипед?
heavycharged
это вообще под эту задачу не подходит
heavycharged
покажи как ты изменишь состояние используя мьютекс внутри sync.Once, чтобы повторные действия возвращали ошибку
heavycharged
функция переданная в Do получившая переменные через замыкания попадает в дата рейс, если внутри stop будет проверка на статус .
Nikita
Ты напиши пример кода, а я тебе скажу, будет ли там датарейс, а то пока это все слишком абстрактно
heavycharged
type runner struct { once *sync.Once isStopping bool } func (r *runner) stop() error { if r.isStopping { return errors.New("is stopping...") } r.once.Do(func() { r.isStopping = true }) return nil }
Nikita
type runner struct { once *sync.Once isStopping bool } func (r *runner) stop() error { if r.isStopping { return errors.New("is stopping...") } r.once.Do(func() { r.isStopping = true }) return nil }
Эта хрень юзается так ` type runner struct { once sync.Once } func (r *runner) stop() { r.once.Do(func() { // my stop logic there }) } `
Dmitri
Это я так выражаю свою точку зрения о том, что "я решил проблему путем взлома идешки" - говенный повод для гордости
Leonid
там кроме инвесторов еще наши коллеги сидят, им семьи тоже надо кормить
Leonid
Коллеги не получают % с продаж, инфа сотка.
а ЗП им платят из воздуха или от продаж?
Leonid
из продаж?
Leonid
я сказал что-то про уврень? где? я сказал, что контора платит зп с продаж. я где-то нарушил логику?
Pavel
а ЗП им платят из воздуха или от продаж?
Коллег нанимают пилить фичи за оклад. Размер оклада не связан с продажами, несмотря на то, что деньги могут идти с продаж (но ФОТ может состоять не только из денег с продаж). Decoupling motherfucker, do you know it? 😄
Viktor
Ребятишки, а вы не можете финансовую сторону ПО обсуждать где-то в другом месте?
Leonid
банальная логика: контора зарабатывает продажей софта, значит прибыли у них с нее, значит ЗП платится с продаж. или в экономике придумали новые схемы?
Viktor
А вы как сюда попали?
Через постель
Dmitri
Тупая привычка - считать чужие доходы
Pavel
Тупая привычка - считать чужие доходы
Финансовые рынки так и работают, кек.
Dmitri
Да-да, и это основание для гордости я-у-мамы-пиратов?
Daniel
Так
Daniel
Кто еще напишет про пиратство - сутки ro
Daniel
За пропаганду гомосексуализма (взлома платных продуктов при наличии бесплатных альтернатив) - перманентно
Dmitri
На всякий случай уточню: пиратство пропагандировать нельзя, или порицать?
Pavel
(в правилах)
Nikita
Гомосексуальность - это немножко другое, если что
Daniel
Это в хорошем смысле слова
Alexander
Гомосексуальность - это немножко другое, если что
тут в плохом смысле было. не в контексте половой ориентации
Daniel
Не
Мерль
Для больших тоже
Тут уже можно поспорить
Kirill
у меня на проекте сейчас 3.5млн строк гошного кода
Kirill
вполне комфортно