Skip to content

Commit

Permalink
Merge branch 'main' into fix-lint
Browse files Browse the repository at this point in the history
  • Loading branch information
serprex authored Dec 25, 2023
2 parents 0f34b18 + b86f106 commit e35d8ff
Show file tree
Hide file tree
Showing 7 changed files with 185 additions and 77 deletions.
17 changes: 11 additions & 6 deletions flow/activities/flowable.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,9 @@ func (a *FlowableActivity) SetupMetadataTables(ctx context.Context, config *prot
}
defer connectors.CloseConnector(dstConn)

flowName, _ := ctx.Value(shared.FlowNameKey).(string)
if err := dstConn.SetupMetadataTables(); err != nil {
a.Alerter.LogFlowError(ctx, config.Name, err)
a.Alerter.LogFlowError(ctx, flowName, err)
return fmt.Errorf("failed to setup metadata tables: %w", err)
}

Expand Down Expand Up @@ -112,7 +113,7 @@ func (a *FlowableActivity) EnsurePullability(

output, err := srcConn.EnsurePullability(config)
if err != nil {
a.Alerter.LogFlowError(ctx, config.PeerConnectionConfig.Name, err)
a.Alerter.LogFlowError(ctx, config.FlowJobName, err)
return nil, fmt.Errorf("failed to ensure pullability: %w", err)
}

Expand Down Expand Up @@ -169,7 +170,8 @@ func (a *FlowableActivity) CreateNormalizedTable(

setupNormalizedTablesOutput, err := conn.SetupNormalizedTables(config)
if err != nil {
a.Alerter.LogFlowError(ctx, config.PeerConnectionConfig.Name, err)
flowName, _ := ctx.Value(shared.FlowNameKey).(string)
a.Alerter.LogFlowError(ctx, flowName, err)
return nil, fmt.Errorf("failed to setup normalized tables: %w", err)
}

Expand Down Expand Up @@ -580,7 +582,8 @@ func (a *FlowableActivity) replicateQRepPartition(ctx context.Context,
slog.Error("failed to pull records", slog.Any("error", err))
goroutineErr = err
} else {
err = monitoring.UpdatePullEndTimeAndRowsForPartition(ctx, a.CatalogPool, runUUID, partition, numRecords)
err = monitoring.UpdatePullEndTimeAndRowsForPartition(ctx,
a.CatalogPool, runUUID, partition, numRecords)
if err != nil {
slog.Error(fmt.Sprintf("%v", err))
goroutineErr = err
Expand Down Expand Up @@ -935,7 +938,8 @@ func (a *FlowableActivity) ReplicateXminPartition(ctx context.Context,
},
}
}
updateErr := monitoring.InitializeQRepRun(ctx, a.CatalogPool, config, runUUID, []*protos.QRepPartition{partitionForMetrics})
updateErr := monitoring.InitializeQRepRun(
ctx, a.CatalogPool, config, runUUID, []*protos.QRepPartition{partitionForMetrics})
if updateErr != nil {
return updateErr
}
Expand All @@ -945,7 +949,8 @@ func (a *FlowableActivity) ReplicateXminPartition(ctx context.Context,
return fmt.Errorf("failed to update start time for partition: %w", err)
}

err = monitoring.UpdatePullEndTimeAndRowsForPartition(errCtx, a.CatalogPool, runUUID, partition, int64(numRecords))
err = monitoring.UpdatePullEndTimeAndRowsForPartition(
errCtx, a.CatalogPool, runUUID, partition, int64(numRecords))
if err != nil {
slog.Error(fmt.Sprintf("%v", err))
return err
Expand Down
19 changes: 19 additions & 0 deletions ui/app/api/mirrors/alerts/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,22 @@ export async function POST(request: Request) {
}
return new Response(JSON.stringify(mirrorStatus));
}

// We accept a list here in preparation for a Select All feature in UI
export async function PUT(request: Request) {
const { mirrorIDStringList } = await request.json();
const mirrorIDList: bigint[] = mirrorIDStringList.map((id: string) =>
BigInt(id)
);
const success = await prisma.flow_errors.updateMany({
where: {
id: {
in: mirrorIDList,
},
},
data: {
ack: true,
},
});
return new Response(JSON.stringify(success.count));
}
7 changes: 3 additions & 4 deletions ui/app/mirrors/edit/[mirrorId]/cdcDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,9 @@ function CdcDetails({ syncs, createdAt, mirrorConfig }: props) {
</Label>
</div>
<div>
<MirrorError
detailed
flowName={mirrorConfig?.flowJobName || ''}
/>
<Label>
<MirrorError flowName={mirrorConfig?.flowJobName || ''} />
</Label>
</div>
</div>
<div className='basis-1/4 md:basis-1/3'>
Expand Down
57 changes: 57 additions & 0 deletions ui/app/mirrors/errors/[mirrorName]/ackbutton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
'use client';
import { Button } from '@/lib/Button';
import { Label } from '@/lib/Label';
import { ProgressCircle } from '@/lib/ProgressCircle';
import { useState } from 'react';
import { toast } from 'react-toastify';

const notifyErr = (errMsg: string) => {
toast.error(errMsg, {
position: toast.POSITION.BOTTOM_CENTER,
});
};

const AckButton = ({ ack, id }: { ack: boolean; id: number | bigint }) => {
const [loading, setLoading] = useState(false);
const [updated, setUpdated] = useState(false);
// handleAck updates ack to true for the given mirrorID
const handleAck = async (mirrorID: bigint | number) => {
setLoading(true);
const updateResResult = await fetch('/api/mirrors/alerts', {
method: 'PUT',
body: JSON.stringify({
mirrorIDStringList: [mirrorID.toString()],
}),
});
const updateRes = await updateResResult.json();
setLoading(false);
if (!updateRes) {
notifyErr('Something went wrong when trying to acknowledge');
return;
}
setUpdated(true);
};
return (
<>
{ack !== true && updated !== true ? (
<Button variant='normalSolid' onClick={() => handleAck(id)}>
<Label as='label' style={{ fontSize: 13 }}>
{loading ? (
<ProgressCircle variant='intermediate_progress_circle' />
) : (
'Acknowledge'
)}
</Label>
</Button>
) : (
<Button variant='normal' disabled={true}>
<Label as='label' style={{ fontSize: 13 }}>
Acknowledged
</Label>
</Button>
)}
</>
);
};

export default AckButton;
119 changes: 72 additions & 47 deletions ui/app/mirrors/errors/[mirrorName]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import prisma from '@/app/utils/prisma';
import TimeLabel from '@/components/TimeComponent';
import { Label } from '@/lib/Label';
import { Table, TableCell, TableRow } from '@/lib/Table';
import { ToastContainer } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import AckButton from './ackbutton';

type MirrorErrorProps = {
params: { mirrorName: string };
Expand All @@ -14,62 +17,84 @@ const MirrorError = async ({ params: { mirrorName } }: MirrorErrorProps) => {
flow_name: mirrorName,
error_type: 'error',
},
distinct: ['error_message'],
orderBy: {
error_timestamp: 'desc',
},
});

return (
<div style={{ padding: '2rem' }}>
<Label variant='title2'>Error Log</Label>
<hr></hr>
<div style={{ marginTop: '1rem' }}>
<Label variant='body'>
<b>Mirror name</b>:
</Label>
<Label variant='body'>{mirrorName}</Label>
<div
style={{
fontSize: 15,
marginTop: '1rem',
width: '100%',
border: '1px solid rgba(0,0,0,0.1)',
padding: '1rem',
borderRadius: '1rem',
}}
>
<Table
header={
<TableRow style={{ textAlign: 'left' }}>
<TableCell>Type</TableCell>
<Label as='label' style={{ fontSize: 15 }}>
Time
</Label>
<TableCell>Message</TableCell>
</TableRow>
}
<>
<div style={{ padding: '2rem' }}>
<Label variant='title2'>Error Log</Label>
<hr></hr>
<div style={{ marginTop: '1rem' }}>
<Label variant='body'>
<b>Mirror name</b>:
</Label>
<Label variant='body'>{mirrorName}</Label>

<div>
<Label as='label' style={{ fontSize: 14, marginTop: '1rem' }}>
Here you can view error logs for your mirror and mark them as
acknowledged. Once all errors are acknowledged, we will show the
status for this mirror as Active.
<br></br>
This is purely for displaying mirror status and has{' '}
<b>no effect on the mirror</b>.
</Label>
</div>

<div
style={{
fontSize: 15,
marginTop: '1rem',
maxHeight: '50em',
overflow: 'scroll',
width: '100%',
border: '1px solid rgba(0,0,0,0.1)',
padding: '1rem',
borderRadius: '1rem',
}}
>
{mirrorErrors.map((mirrorError) => (
<TableRow key={mirrorError.error_message}>
<TableCell style={{ color: '#F45156', width: '10%' }}>
{mirrorError.error_type.toUpperCase()}
</TableCell>
<TableCell style={{ width: '20%' }}>
<TimeLabel
fontSize={14}
timeVal={mirrorError.error_timestamp.toLocaleString()}
/>
</TableCell>
<TableCell style={{ width: '70%', fontSize: 13 }}>
{mirrorError.error_message}
</TableCell>
</TableRow>
))}
</Table>
<Table
header={
<TableRow style={{ textAlign: 'left' }}>
<TableCell>Type</TableCell>
<TableCell>
<Label as='label' style={{ fontSize: 15 }}>
Time
</Label>
</TableCell>
<TableCell>Message</TableCell>
<TableCell></TableCell>
</TableRow>
}
>
{mirrorErrors.map((mirrorError) => (
<TableRow key={mirrorError.id}>
<TableCell style={{ color: '#F45156', width: '10%' }}>
{mirrorError.error_type.toUpperCase()}
</TableCell>
<TableCell style={{ width: '20%' }}>
<TimeLabel
fontSize={14}
timeVal={mirrorError.error_timestamp}
/>
</TableCell>
<TableCell style={{ width: '50%', fontSize: 13 }}>
{mirrorError.error_message}
</TableCell>
<TableCell style={{ width: '20%', fontSize: 13 }}>
<AckButton ack={mirrorError.ack} id={mirrorError.id} />
</TableCell>
</TableRow>
))}
</Table>
</div>
</div>
</div>
</div>
<ToastContainer />
</>
);
};

Expand Down
41 changes: 22 additions & 19 deletions ui/app/mirrors/mirror-status.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,21 @@ export const ErrorModal = ({ flowName }: { flowName: string }) => {
<Link href={`/mirrors/errors/${flowName}`}>
<Button
style={{
backgroundColor: 'rgba(240, 128, 128, 0.5)',
backgroundColor: 'rgba(240, 128, 128, 0.2)',
height: '2rem',
boxShadow: '0 2px 4px rgba(0, 0, 0, 0.2)',
border: '1px solid rgba(0, 0, 0, 0.2)',
}}
>
<Label as='label' style={{ fontSize: 13, color: 'darkred' }}>
Show errors
<Icon name='error' />
<Label as='label' style={{ fontSize: 13 }}>
Errors
</Label>
</Button>
</Link>
);
};

export const MirrorError = ({
flowName,
detailed,
}: {
flowName: string;
detailed: boolean;
}) => {
export const MirrorError = ({ flowName }: { flowName: string }) => {
const [flowStatus, setFlowStatus] = useState<string>();
const [isLoading, setIsLoading] = useState<boolean>(true);
const [error, setError] = useState<string | null>(null);
Expand Down Expand Up @@ -81,15 +76,23 @@ export const MirrorError = ({
);
}

if (flowStatus == 'healthy') {
if (detailed)
return (
<div style={{ display: 'flex', alignItems: 'center' }}>
if (flowStatus === 'healthy') {
return (
<Link href={`/mirrors/errors/${flowName}`}>
<Button
style={{
backgroundColor: 'white',
height: '2rem',
border: '1px solid rgba(0, 0, 0, 0.1)',
}}
>
<Icon name='check_circle' fill={true} />
<Label>Healthy</Label>
</div>
);
return <Icon name='check_circle' fill={true} />;
<Label as='label' style={{ fontSize: 13 }}>
Active
</Label>
</Button>
</Link>
);
}

return <ErrorModal flowName={flowName} />;
Expand Down
2 changes: 1 addition & 1 deletion ui/app/mirrors/tables.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export function CDCFlows({ cdcFlows }: { cdcFlows: any }) {
<TimeLabel timeVal={flow.created_at} />
</TableCell>
<TableCell>
<MirrorError flowName={flow.name} detailed={false} />
<MirrorError flowName={flow.name} />
</TableCell>
<TableCell>
<DropDialog
Expand Down

0 comments on commit e35d8ff

Please sign in to comment.