-
Notifications
You must be signed in to change notification settings - Fork 3
Home
Mail-Funnel Client Documentation.
Funnel-Builder Javascript Application
The Funnel-Builder is built using the JQuery Flowchart Library, here is the API - https://github.com/sdrdis/jquery.flowchart
The javascript flowchart (canvas) is built from a JSON String, that specifies where each node is placed on the chart, and the functionality of each node (The JS Callback when a node is selected).
When a node is selected, it can be edited, which launches a modal window. The modal windows and their content are generated when the page is loaded, and hidden, until the node is selected and the edit button is clicked, and then that node's modal window is displayed with it's data populated in the form.
The issue came up with the XY Axis of each node. When the page is loaded, each The Node's X and Y Axis need to be calculated based on the window size (width). So the issue is that the controller constructs the JSON String and passes it down to the view.
Controller (Constructs JSON String) -->> View (Uses JSON String)
The issue is that the Window width is loaded in the View. After the JSON String to build the Flowchart's Canvas was already built, including each Node's XY Coordinate. So we needed a way to pass the width of the window to the code API that builds the Canvas. So the system was re-designed like this.
Controller -> View -> AJAX (On-Load) -> FunnelBuilder-API -> Returns Canvas JSON -> View Re-Generates Canvas w/ JSON
Controller: Campaign ID variables passed down to view.
View: Gets the Campaign_ID, Hook_ID, App_ID and calculates the window width. Makes an AJAX Call immediately, passing all that data
AJAX-Call: The AJAX Call is made to the Client's local JSON API Server, passing it those variables to construct the canvas.
Funnel-Builder local JSON API Server running on Client: It takes those variables from the view, including the screen width and campaign ID, builds and returns the JSON String, for the canvas, from those values.
View: The view receives the JSON built for the canvas, including the correctly placed node's XY coordinates, and it re-loads the canvas components from this JSON String.
(** This all happens immediately on page-load, giving the appearance that is's happening when the page loads, but really, the pages loads and then it makes the JSON Call, and then it re-generates the chart)
Edit / Update Node Feature
Initially the modal windows were generated when the page loads, but hidden from the user, until the edit button was clicked, and then each Job's form would appear in a modal window. We ran into an issue with the XY coordinates where we had to implement AJAX, so we added that functionality here accordingly.
The page still generates all the edit-forms and their modal windows, hidden. But now, when a node is edited, when we click "Save", an AJAX call checks if the form content differs from the Job's actual data, and if it is, we know it's been updated and update the Job on the REST Server. Then we update the data saved in the modal window, and hide it again. We may remove the initially loaded data from the constructor all-togethor soon but not sure yet.
New Node When a new node is created, it is placed on the chart. We can handle this two ways: A) When we create the node, we display an empty form, the user fills out the form, and when he submits it, we generate the Job on the server over REST and re-load the canvas with fresh data. This leaves less room for error.
B) Or we create the node, and leave it until the user saves the chart. When the user saves the chart, we iterate over the new nodes created, and add them all.
Delete Node
A) Delete the node when the button is pressed, using AJAX, and then re-load the canvas with fresh data. B) Delete the nodes, then when the user saves the chart, iterate over the chart data and delete all the nodes that do not exist.
Server-Side
When we create, update and delete Jobs on the server, we are doing two things. A) Creating, updating or deleting a job from the Jobs table. This is the table that is primarily used for all Jobs. B) We are ALSO adding, deleting, or deleting-then re-adding (an update) Jobs from the Job queue, for the Resque job-queue worker that uses a Redis backend.
We use Resque-Scheduler which allows us to schedule jobs in the queue that will be executed in the future. We obviously add the entries in the future, based on the user selection in the Funnel-Builder when he creates / updates the job. The limitation here is that we can only create and delete entries from the job-queue. So to update jobs, we actually query the job(s) in the Redis Queue for that job, and delete them and then re-add them.
** Job-Queue and its relationship with the Jobs Table **
When we add a job to the job-queue, if we are specifying that we want to run the job at a specified time for the next 3 days, we are creating 1 job in the job table, and adding 3 jobs to the queue. We are adding a job to the queue for each day. So if we want a job to execute thrice, we add a job for tomorrow, one in two days, and another in 3 days, all at the specified time.
Data Integrity / Semaphore Locks
To protect data integrity, we have also added a lock to each app using the funnel-builder. When we are modifying an app's job data, we set the lock on the app, on the server in the app table, to true. This means we are modifying the app's job data and prevents other clients logged-in from modifying the data at the same time and corrupting data. Furthermore, we get the last-modified time of the app, and we are adding functionality to constantly check that time (ever 5-10 seconds) using AJAX. If that time changes, it means that somebody else modified the data while we are in the funnel-builder - and to prevent data corruption, we notify the user and suggest he re-load the data because it may be corrupt.
After jobs execute, notify the Jobs table its executed
We need to add a function to the Resque job queue system that runs everytime after a job is executed. In Resque, you can add a hook to be run before, during and after a job is processed. We need to add a hook to run after the job is processed that modifies the Job in the Jobs table, and says how many times the jobs been run.