실제 채용 아니라, 가상 질문에 대한 브레인 스토밍을 위한 스레드입니다.
우리 회사의 주요 고객은 아래 사항들을 요구하였습니다.
요구사항 듣는데 제가 이상한것일까요? -
자유게시판 - 닷넷데브
이를 해결할 인재를 채용 중입니다.
특히 2번과 관련하여, 본인이라면 어떻게 구현할 지 설명해주세요.
실제 채용 아니라, 가상 질문에 대한 브레인 스토밍을 위한 스레드입니다.
우리 회사의 주요 고객은 아래 사항들을 요구하였습니다.
요구사항 듣는데 제가 이상한것일까요? -
자유게시판 - 닷넷데브
이를 해결할 인재를 채용 중입니다.
특히 2번과 관련하여, 본인이라면 어떻게 구현할 지 설명해주세요.
뭔가 말 잘못하면 엄청 까일것 같지만
저같으면 일단 웹소켓을 써서 하겠지만 그리드 에서는
좀 애매할것 같긴 합니다.뭐 생성일 기준으로 하계지만
저는 개인적으로 이것보다 ; UNDO ,REDO 이걸 어찌 해결하나 더 고민이긴 해요
브라우저 스토리지를 써야하나 하고요 근데 진짜 채용진행즁이신가요
실제 채용 아닙니다. ^^.
그저 주제가 재미있어서 올려 봤습니다.
브레인 스토밍 정도로 생각하면 좋겠습니다.
그리고, Redo Undo 는 보통 두 개의 Stack 을 사용하는 게 정석처럼 받아들여지고 있습니다. 후진용 스택 하나, 전진용 스택 하나죠.
후진 스택은 Diff가 발생할 때 마다 Push 되고, 이때 전진 스택은 Clear 됩니다.
후진은 데이터를 후진 스택에서 전진 스택으로 옮기는 것이고, 전진은 전진 스택에서 후진 스택으로 옮기는 것입니다.
그런데 Diff 를 언제, 어떻게 결정할 것인지, 스택에 raw 데이터를 저장할 지, 압축을 할지, Diff 만 저장할 것인지 등의 디테일에 악마가 살고 있습니다.
그 스택을 저장할 메모리를 JQUERY 로 해결해야 할지 또 카운트는 10개로 해달라고 하고 아이구 이건 웹인데
글쎄요.
Redo/Undo 는 편집 컨텍스트로 한정할 필요가 있습니다.
편집이 완료되어 커밋하기 전에는, I/O 가 개입할 필요가 없다는 의미입니다.
편집 컨테스트는 현재 프로세스 내부의 문제라 스택의 capacity 문제가 크게 중요하지 않습니다.
IDE 나 이 포럼의 편집 창에 꽤 긴 히스토리가 담기는 것도 그런 이유입니다.
다만 커밋이 이뤄지면 히스토리는 지워집니다.
뭔가 CONTEXT 라고 하니까 그 개념으로 생각해봐야겠군요
좋은 조언입니다 따로 생각하는것이 아니라 CONTEXT 개념으로 접근하낟.
노가다로 해결될 문제가 아닐걸요?
Grid 는 상태를 표출하는 UI 이고, DB는 마지막 상태의 저장입니다.
주어진 도메인 문제에서 이 둘이 끼어들 여지는 없는 것 같습니다.
닷넷이니까 SignalR로 전 쓰겠습니다. Redo, Undo도 서버에서 처리하면 되겠죠…
웹이라면 signalr을 사용한 동시성 처리 로직을 구성해서 redis 캐싱으로 데이터 1차 저장하고 주기적으로 혹은 클라에서 특정 완료 처리 기준 시 db 저장하는 방식으로 생각은 해볼 수 있을 거 같긴 해요. 병렬 처리에 대한 무결성, 정합성, 일관성을 보장할 수 있게 구현만 잘 되면 될 거 같긴 합니다.
undo, redo에 대한 부분도 어느 시점을 redis에 저장해둘 것인가를 기준삼아서 1분 혹은 30초마다 임시 저장을 해서 undo를 했을 때 그 이전 시점으로 돌아간다던가 아니면 클라에서 어떤 저장 기준이 있으면 좀 더 기준이 명확해져서 구현이 쉬워질 거구요. 그리고 undo했을 때 redis 다시 저장해두었다가 redo를 한다던가 할 수 있을 거 같긴 한데요. 이 부분도 동시성이 중요한 부분이라 redis pub/sub으로 처리하면 좋지 않을까 싶긴 합니다. 그 이후 db에 최종 저장하는 시점을 정하면 될 거 같고요.
Redis 를 쓰기 부담스러운 환경이라면 다른 대안이 있을까요?? cache 메모리 db 가 있다지마 어딘가 못미더워 보이고요
구체적인 정보가 부족해서, 지원율이 낮은가 봅니다. ^^.
시스템 구성을 구체적으로 제시해 보는 건 어떨까요?
이렇게 하면, “나라면 이렇게 하겠다” → “환경이 받쳐주지 않는다” 식의 문답이 되풀이 되는 것을 막을 수 있을 것 같습니다.
특히 윗 댓글에 나타난 그림은 FE 가 직접 DB에 접근해야 하는 환경이라고 해석할 수 있어서, 별도의 서버가 필요로 하는 SignalR 등의 방법이 용이하지 않은 것처럼 보이기도 합니다.
중간 백엔드가 없다는 걸 표현하신건가요?
아니면 저 "WEB PAGE"라는게 웹 서버에서 내려주는 걸 말할까요?
아, 왜 굳이 이렇게 여쭈었냐면, 요즘은 Static page라는게 존재해서 입니다.
그리고 cache는 말 그대로 cache라서, 사용하는 사용자들도 "언제든 날아갈수 있는 휘발성 데이터"라는걸 인지 해 두는게 좋을 것 같습니다.
그런 이유, 잠깐 동안만의 짧은 변경 이력과, 버전 관리에 가까운 긴 변경 이력 두개가 필요 할 것 같습니다.
Undo, Redo(짧은 이력, local)를 언제나 가능할 것이라고 믿는게 오히려 이상하지 않을까요?
office 365나 구글 시트도 그렇게까진 안 했던 것 같다고 느꼈습니다.
그냥 일정 시간마다의 스냅샷을 기준으로 변경 이력(긴 이력) 추적만 했던 것 같아요.
전자는 cache를 이용해 간단히 구현하고, 언제든 날아갈 수 있다는 전제 하에 작업 하고,
후자는 DB등에 사용자별 또는 문서 단일의 사용자+편집시간+diff 정도로 이력을 남기면 좋을 것 같습니다.
긴 버전 관리가 각 행의 변경 이력을 추적한다는 의미라면, 간단히 행이 10000 개 라고 가정하더라도, 이력 관리를 위한 데이터가 만만치 않을 것 같은데요.
각 행 마다 혹은 각 테이블 마다 깃 저장소를 두는 형국이 될 것이라, 개별 기업이 감당이 가능할런지 모르겠습니다.
단순히, 특정 행을 편집하는 순간부터, 로컬 히스토리와 외부 업데이트 사이의 관리만 하면 될 것 같은데 말이죠.
시나리오를 짜자면,
웹페이지는 일정 주기로 그리드를 업데이트 계속하고, (Normal State)
행을 편집하는 순간, 편집 화면이 그리드를 덮어 안보이게 만들고
아이템 서비스는 그리드 아이템 전체가 아닌 편집 중인 아이템의 업데이트만 Polling.
히스토리는 로컬 캐시만 관리. 편집 중에 외부 업데이트가 있다면,
누군가 님보다 빨리 업데이트해서, 편집 다시 해야 함
메시지 띄우고, 히스토리 Clear.
편집이 끝나면, 그리드 보여줌 (Normal state)
이때, 편집한 행이 업데이트 되면, 로컬 캐시 지움.(Redo, Undo 불가)
안되면, 캐시가 살아 있어, Redo Undo 가능.
웹 페이지는 그리드 아이템 별 히스토리 List 관리함.
웹 페이지 떠나면, List clear.
sheet를 기준으로 보자면,
diff 의 크기가 별로 크지 않을 가능성도 있어 보입니다.
특정 셀의 변경점만 관리하면 되는 것 아닐까요?
아무리 1만개 행의 데이터라고 하더라도,
데이터를 전부 1만개씩 이력을 남기지는 않을 것 같거든요.
그래서 결과적으로는 git 저장소와 비슷한 느낌이 되겠지만
파일 저장하는 주기를 정할 수 있다는 점도 차이가 있을 듯 합니다.
폭넓게 오늘 하루 변경점을 전부 뭉뚱그려도 무방한 상황도 나올 수 있을 테고요.
diff 관리가 복잡하다 그러면, 로컬 차이만 남기고 daily이상은 백업으로 파일 보관만 하는 식도 괜찮을 것 같습니다.
실시간에 가까운 약 1시간~24시간 이내의 변경점만 git과 유사하게 관리하는 식이거나요.
너무 google sheet를 clone하는 아이디어에 붙잡혀 있는건가 싶으면,
다른 방법도 고민 해보면 좋을 것 같네요.
이러면 해결될 것 같습니다! ㅋㅋㅋㅋㅋ
이정도가 있는데 2번은 클라이언트가 요구하는 기능이랑은 좀 거리가 있어서
1번으로 충돌을 허용하고 클라이언트에게 인지하게 하는게 나을거같네요
2번도 동시접근 관리하는 것도 일이겠구요
제대로 답변한건진 모르겠습니다만
+제가한 답변은 빙산의 일각이긴 하네요
ㅋㅋㅋㅋ 고생많으십니다…
그냥 프론트단에 iframe으로 구글시트를 붙여버리십시요…
내가 구글시트 붙이는거 구현했다 하시면됩니다.
제 생각에는요 REDO/UNDO 는 말씀데로 로컬에서만 작동을 하면 될것 같고요 외부 또는 로컬에서 I/O 가 일어나면 어떤 필드가 어떻게 바뀌었는지 I/O 기록에 남기고 시그널R로 해당내용을 전송해서 편집중인 사람의 화면을 블럭시키고 가운데 다이얼로그 띄워서 어떤 내용이 어떻게 바뀌었는지 알려줍니다. 예를들어
aa 님이 데이터 bb 를 수정하였습니다.
“A 필드 값 oo → xx 로 변경됨”
이런 식으로요. 그다음에 확인을 누르면 그 다이얼로그와 블럭만 없어지고요 편집중인 REDO/UNDO를 포함한 현재 컨텍스트는 그대로 있습니다. 왜냐면 수정한 사람이 잘못했거나 할 수도 있으니까요 그럼 이제 편집중인 사람이 바뀐 정보를 확인했으니 이 정보를 다시 업데이트 할지 아니면 화면을 나가서 REDO/UNDO 컨텍스트와 함께 자신의 편집 과정을 초기화 할 것인지는 본인이 선택하면 되지 않을까 합니다. 그리고 다시 확인 할때는 I/O 기록에 어떤 부분이 바뀌어있는지는 기록이 되어 있을테니 헷깔리지 않을 것 같아요.
작은 기업의 경우 I/O 작업자체가 많이 없을테니 그냥 한 서버에서 채널하나 더 만들어서 시그널R 통신하는 건 부담스럽지 않을 것 같고요 I/O 작업이 많을 것 같으면 시그널R 애저호스팅 이용하면 될 것 같습니다. 사용량에 비해 요금이 저렴하더라고요.
모델간 필드 수정여부의 경우 object 를 인자로 받아서 타입이 같은지 검사하고 모든 property 별로 for문 돌려서 비교모델의 property 값과 비교해서 틀리면 히스토리로 남기는 건 괜찮더라고요. 그전에 property에 [Display(Name=””)] 같은 attribute 를 넣어서 필드명이 뭔지 표시도 하고요.
요즘 추세가 예전에 비해서 점점 더 실시간 반응을 요구하는 경향이 늘어나는것 같긴 하네요. ㅎㅎ
히스토리에 대역폭(저장, 전송)이 결부되면, 압축이 필요하죠.