Data.tsx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. import {
  2. createContext,
  3. useCallback,
  4. useContext,
  5. useEffect,
  6. useState,
  7. useRef,
  8. } from 'react';
  9. import { io, Socket } from 'socket.io-client';
  10. import { authContext } from '@/context';
  11. import { url, Collection, MilvusService, Database } from '@/http';
  12. import { checkIndexBuilding, checkLoading } from '@/utils';
  13. import { DataContextType } from './Types';
  14. import { WS_EVENTS, WS_EVENTS_TYPE } from '@server/utils/Const';
  15. import { LAST_TIME_DATABASE } from '@/consts';
  16. export const dataContext = createContext<DataContextType>({
  17. loading: false,
  18. collections: [],
  19. setCollections: () => {},
  20. database: 'default',
  21. setDatabase: () => {},
  22. databases: [],
  23. setDatabaseList: () => {},
  24. });
  25. const { Provider } = dataContext;
  26. export const DataProvider = (props: { children: React.ReactNode }) => {
  27. // local data state
  28. const [collections, setCollections] = useState<Collection[]>([]);
  29. const [connected, setConnected] = useState(false);
  30. const [loading, setLoading] = useState(false);
  31. const [database, setDatabase] = useState<string>(
  32. window.localStorage.getItem(LAST_TIME_DATABASE) || 'default'
  33. );
  34. const [databases, setDatabases] = useState<string[]>(['default']);
  35. // auth context
  36. const { isAuth, clientId } = useContext(authContext);
  37. // socket ref
  38. const socket = useRef<Socket | null>(null);
  39. // socket callback
  40. const socketCallBack = useCallback(
  41. (data: any) => {
  42. const collections: Collection[] = data.map((v: any) => new Collection(v));
  43. const hasLoadingOrBuildingCollection = collections.some(
  44. v => checkLoading(v) || checkIndexBuilding(v)
  45. );
  46. setCollections(collections);
  47. // If no collection is building index or loading collection
  48. // stop server cron job
  49. if (!hasLoadingOrBuildingCollection) {
  50. MilvusService.triggerCron({
  51. name: WS_EVENTS.COLLECTION,
  52. type: WS_EVENTS_TYPE.STOP,
  53. });
  54. }
  55. },
  56. [database]
  57. );
  58. // http fetch collection
  59. const fetchCollection = async () => {
  60. try {
  61. setLoading(true);
  62. const res = await Collection.getCollections();
  63. setCollections(res);
  64. setLoading(false);
  65. } catch (error) {
  66. console.error(error);
  67. } finally {
  68. setLoading(false);
  69. }
  70. };
  71. const fetchDatabase = async () => {
  72. const res = await Database.getDatabases();
  73. setDatabases(res.db_names);
  74. };
  75. useEffect(() => {
  76. if (isAuth) {
  77. // fetch db
  78. fetchDatabase();
  79. // connect to socket server
  80. socket.current = io(url as string);
  81. // register client
  82. socket.current.emit(WS_EVENTS.REGISTER, clientId);
  83. socket.current.on('connect', function () {
  84. console.log('--- ws connected ---', clientId);
  85. setConnected(true);
  86. });
  87. socket.current?.on(WS_EVENTS.COLLECTION, socketCallBack);
  88. } else {
  89. socket.current?.disconnect();
  90. // clear collections
  91. setCollections([]);
  92. // clear database
  93. setDatabases(['default']);
  94. // set connected to false
  95. setConnected(false);
  96. }
  97. }, [isAuth]);
  98. useEffect(() => {
  99. if (connected) {
  100. // clear data
  101. setCollections([]);
  102. // remove all listeners
  103. socket.current?.offAny();
  104. // listen to collection event
  105. socket.current?.on(WS_EVENTS.COLLECTION, socketCallBack);
  106. // get data
  107. fetchCollection();
  108. }
  109. }, [socketCallBack, connected]);
  110. return (
  111. <Provider
  112. value={{
  113. loading,
  114. collections,
  115. setCollections,
  116. database,
  117. databases,
  118. setDatabase,
  119. setDatabaseList: setDatabases,
  120. }}
  121. >
  122. {props.children}
  123. </Provider>
  124. );
  125. };